将 class 的 subclass 作为类型参数传递(类型参数为 subclass)
Pass subclass of class as type parameter (type parameter is subclass)
让我们考虑一下:
public class Text extends BinaryComparable
implements WritableComparable<BinaryComparable> {
我们可以看出Text
是BinaryComparable
.
那么,再考虑一下
@InterfaceAudience.Public
@InterfaceStability.Stable
public interface WritableComparable<T> extends Writable, Comparable<T> {
我在 Scala 中有一些 class:
trait MyClass[A <: WritableComparable[A]] {
无法创建
MyClass[Text] = new MyClass[Text]()
由于类型不匹配。为什么?毕竟Text
就是BinaryComparable
怎么解决呢?
WritableComparable[BinaryComparable]
与 WritableComparable[Text]
不同或超类型,因为 WritableComparable
在 T
中是不变的(Java 泛型实际上并不有协变或逆变)。
如果 WritingComparable
被声明为 trait WritingComparable[-A]
,那么它将 compile。
不过,您的最后一个代码片段没有多大意义,因为 MyClass
不采用 2 个类型参数(正如 Luis Miguel Mejia Suarez 提到的)。你不应该得到一个类型不匹配的错误,它应该告诉你你有太多的参数。我想你的意思只是 MyClass[Text]
.
Here是一个关于不变性、逆变性和协变性的问题。
你可以试试多加一个类型参数
trait MyClass[B >: A, A <: WritableComparable[B]]
val mc: MyClass[BinaryComparable, Text] = new MyClass[BinaryComparable, Text] {}
与 trait MyClass[A <: WritableComparable[_ >: A]]
相反,这不会产生 illegal cyclic reference
。
或者,您可以将 MyClass
中的边界定义为
trait MyClass[B, A <: B with WritableComparable[B]]
val mc: MyClass[BinaryComparable, Text] = new MyClass[BinaryComparable, Text] {}
您甚至可以排除具有存在类型的 B
(如 @user 所建议)
trait MyClass[A <: B with WritableComparable[B] forSome { type B }]
val mc: MyClass[Text] = new MyClass[Text] {}
此类存在类型将在 Scala 3 中弃用
http://dotty.epfl.ch/docs/reference/dropped-features/existential-types.html
让我们考虑一下:
public class Text extends BinaryComparable
implements WritableComparable<BinaryComparable> {
我们可以看出Text
是BinaryComparable
.
那么,再考虑一下
@InterfaceAudience.Public
@InterfaceStability.Stable
public interface WritableComparable<T> extends Writable, Comparable<T> {
我在 Scala 中有一些 class:
trait MyClass[A <: WritableComparable[A]] {
无法创建
MyClass[Text] = new MyClass[Text]()
由于类型不匹配。为什么?毕竟Text
就是BinaryComparable
怎么解决呢?
WritableComparable[BinaryComparable]
与 WritableComparable[Text]
不同或超类型,因为 WritableComparable
在 T
中是不变的(Java 泛型实际上并不有协变或逆变)。
如果 WritingComparable
被声明为 trait WritingComparable[-A]
,那么它将 compile。
不过,您的最后一个代码片段没有多大意义,因为 MyClass
不采用 2 个类型参数(正如 Luis Miguel Mejia Suarez 提到的)。你不应该得到一个类型不匹配的错误,它应该告诉你你有太多的参数。我想你的意思只是 MyClass[Text]
.
Here是一个关于不变性、逆变性和协变性的问题。
你可以试试多加一个类型参数
trait MyClass[B >: A, A <: WritableComparable[B]]
val mc: MyClass[BinaryComparable, Text] = new MyClass[BinaryComparable, Text] {}
与 trait MyClass[A <: WritableComparable[_ >: A]]
相反,这不会产生 illegal cyclic reference
。
或者,您可以将 MyClass
中的边界定义为
trait MyClass[B, A <: B with WritableComparable[B]]
val mc: MyClass[BinaryComparable, Text] = new MyClass[BinaryComparable, Text] {}
您甚至可以排除具有存在类型的 B
(如 @user 所建议)
trait MyClass[A <: B with WritableComparable[B] forSome { type B }]
val mc: MyClass[Text] = new MyClass[Text] {}
此类存在类型将在 Scala 3 中弃用
http://dotty.epfl.ch/docs/reference/dropped-features/existential-types.html