Generics Kotlin中泛型类的扩展函数

Generics Kotlin中泛型类的扩展函数,generics,kotlin,kotlin-extension,Generics,Kotlin,Kotlin Extension,下面的扩展函数有什么问题 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 } } 您的方法plus希望

下面的扩展函数有什么问题

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
    }
}

您的方法
plus
希望参数具有与接收器相同的泛型类型参数
T
。因此,您不能将
Foo
添加到
Foo

如果希望能够添加所有类型的
Foo
,则需要声明扩展函数,如下所示:

operator fun <T,R> Foo<T>.plus(that: Foo<R>): Foo<T> = throw Exception()
操作符fun Foo.plus(that:Foo):Foo=throw Exception()
这个问题是泛型如何工作的核心

class Foo {
    fun <T> T.foo(that: T): T = throw Exception()

    init {
        "str" foo 42
    }
}
现在,
String
Any
的子类型,
Int
Any
的子类型,因此此函数适用于参数

但在你的第一个例子中:

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
    }
}

现在,
Foo
T
中是不变的,因此
Foo
不是
Foo

的一个子类型,我认为安德烈·布雷斯劳接受的答案是正确的,但提供了不正确的解决方案

只需告诉编译器为提供的泛型类型参数推断公共超类型,即,只要Foo的泛型类型参数共享一个公共超类型(它们总是会),就可以使用它。比如:

operator fun <T, R: T, S: T> Foo<R>.plus(that: Foo<S>): Foo<T> = throw Exception()
操作符fun Foo.plus(that:Foo):Foo=throw Exception()
现在,如果类型不匹配,返回的Foo的结果泛型类型参数将根据需要加宽,但操作本身是合法的,不会引入协方差。

>>“我想知道它为什么不同”@Yaroslav与常规函数没有+区别。这只是一个子类型
Foo
Foo
的问题,其中a是B的一个子类型。在Java中,它需要进行任意转换。在Scala上不确定,我相信他们有
Foo[+T]
用于相同的目的
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
    }
}
fun Foo<Any>.plus(that: Foo<Any>): Foo<Any> = ...
class Foo<out 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
    }
}
operator fun <T, R: T, S: T> Foo<R>.plus(that: Foo<S>): Foo<T> = throw Exception()