为什么类型参数边界 T <: Comparable[T] 在 T = Int 时失败?

14 浏览
0 Comments

为什么类型参数边界 T <: Comparable[T] 在 T = Int 时失败?

第二个表达式是类型擦除的结果吗?我该如何定义Foo,以便将其参数化为Int,但仍然能够对其实例变量执行某种排序行为?

0
0 Comments

问题的出现原因是Int类型在Scala中被认为是Java中的int类型的等价物,而int类型并不是一个类,因此不能被视为Comparable。解决方法是使用视图界定(view bounds),这种方法在Scala中被广泛使用来解决类可以实现某个接口但实际上并没有实现的问题,特别是在处理Java类时。程序员们也可以使用视图界定来处理来自库和框架的类似问题,或者只是为了给一个库创建一个Scala风格的包装器。

0
0 Comments

问题的原因是类型参数边界T <: Comparable[T]在T = Int的情况下失败。这是因为Int类型不是Comparable[Int]的子类型。解决方法是使用视图界定(view bound),即将类型参数边界改为T <% Comparable[T]。这样,编译器会在需要时自动进行类型转换,将Int转换为Comparable[Int]。

下面是一个示例代码:

class Foo[T <% Comparable[T]](val x: T)
val foo = new Foo(3)

在这个示例中,我们定义了一个泛型类Foo,它接受一个类型参数T,并要求T能够隐式转换为Comparable[T]。然后我们创建了一个Foo实例,传入一个Int类型的参数3。

通过使用视图界定,编译器会在需要时自动调用Predef.intWrapper将Int类型转换为Comparable[Int]类型。这样,我们就可以成功地创建一个Foo[Int]的实例。

- 类型参数边界T <: Comparable[T]要求T必须是Comparable[T]的子类型。

- 当T = Int时,Int并不是Comparable[Int]的子类型,因此类型参数边界失败。

- 使用视图界定T <% Comparable[T]可以让编译器自动进行类型转换,将Int转换为Comparable[Int],从而满足类型参数边界的要求。

0
0 Comments

问题的出现原因是在使用类型参数边界时,给定的参数类型Int不满足T <: Comparable[T]的约束条件,因为Int类型不是Comparable[Int]的子类型。

解决方法是使用上下文界定(context bound)。上下文界定使用了Ordering[T]或java.util.Comparator[T]的隐式参数来表示在构造函数调用时有一个隐式的Ordering[T]或java.util.Comparator[T]存在。这等效于添加一个隐式参数。

采用这种方式的优点是可以根据上下文使用一个备选的排序方式。

通过在范围内定义一个对象,可以实现使用不同的排序方式:

// 默认情况下,new Foo("a", "c", "b").items == List("a", "b", "c")

class Foo[T: Ordering](xs: T*) {

val items = xs.toList.sorted

}

// 在作用域内定义此对象后,

// new Foo("a", "c", "b").items == List("c", "b", "a")

implicit val descending = Ordering[String].reverse

我之前对上下文界定并不了解,阅读了您的回答后我去查阅了更多资料。非常有用和信息丰富。谢谢。

0