类型推断仅适用于扩展功能

时间:2019-10-28 22:42:10

标签: kotlin

以下代码可以正常工作,并且对foo.get()扩展函数的调用返回了正确的BarImpl类型。

open class Bar
class BarImpl: Bar()

class Foo<T : Bar> 

inline fun <reified T : Bar> Foo<T>.get(): T {
    return SomeMap(this).get(T::class)
}

class Activity {
    lateinit var foo: Foo<BarImpl>
    val barImpl = foo.get()
}

但是当我尝试将Foo<T>.get()移到类中时,类型推断将失败

class Foo<T : Bar> {
    inline fun <reified T : Bar> get(): T {
        return SomeMap(this).get(T::class)
    }
}

class Activity {
    lateinit var foo: Foo<BarImpl>
    val barImpl = foo.get()
}
  

错误:类型推断失败:没有足够的信息来内联fun get()来推断参数T:T   请明确指定。

   val vm = foo.get()
                ^

如何将函数移到类中?

1 个答案:

答案 0 :(得分:4)

扩展功能返回Foo类型参数的结果。因此,可以从接收者类型推断出结果类型。

除了名称,成员函数结果类型与Foo类型参数没有其他共同之处,这对编译器而言毫无意义。通过编写和编译以下代码,您可以看到方法中的T和类中的T是不同的类型:

Foo<BarImpl>().get<BarImpl2>()

如果要使get成为返回Foo类型参数结果的成员函数,则应从函数中删除类型参数并通过构造函数注入类实例:

class Foo<T : Bar>(private val clazz: KClass<T>) {
    fun get(): T {
        return SomeMap(this).get(clazz)
    }

    companion object {
        inline operator fun <reified T : Bar> invoke() = Foo(T::class)
    }
}