我的扩展功能在下面有什么问题
class Foo<T> {
fun <T> Foo<T>.plus(that: Foo<T>): Foo<T> = throw Exception()
init {
Foo<Int>() + Foo<String>() // A receiver of type Foo<T> is required
}
}
Update
我想知道为什么它与常规扩展函数不同,其中T成功地被推断为 Any
并且想要实现相同的行为,例如: G . T被推断为Foo <Any>
class Foo {
fun <T> T.foo(that: T): T = throw Exception()
init {
"str" foo 42
}
}
2 回答
问题是仿制药如何运作的核心问题 .
这是有效的,因为编译器可以找到适合函数签名和参数的
T
:它是Any
,函数变成了这个:现在,
String
是Any
的子类型,Int
是Any
的子类型,因此该函数适用于参数 .但在你的第一个例子中:
它's all different. There' s没有
T
. 让我们天真并尝试Any
:现在,
Foo
在T
中是不变的,所以Foo<Int>
是 notFoo<Any>
的子类型,事实上除了Int
之外没有类型T
会使Foo<T>
成为Foo<Int>
的超类型 . 所以,T
必须完全Int
,但它也必须完全String
由相同的逻辑(因为第二个参数),所以没有解决方案,并且该函数不适用 .您可以通过在
T
中制作Foo
共变体来使其工作:这对
Foo
成员的可能签名施加了一些限制,但如果您对它们没有问题,则可以解决您的问题 .有关详细信息,请查看此链接:http://kotlinlang.org/docs/reference/generics.html
您的方法
plus
要求参数具有与接收方相同的泛型类型参数T
. 因此,您无法将Foo<String>
添加到Foo<Int>
.如果您希望能够添加所有类型的
Foo
,那么您需要声明扩展函数,如下所示: