为什么类型参数绑定T <:Comparable [T]为T = Int失败?

Col*_*lin 13 java scala scala-2.8

scala> class Foo[T <: Comparable[T]](val x : T)
defined class Foo

scala> (3: Int).asInstanceOf[Comparable[Int]]  
res60: java.lang.Comparable[Int] = 3

scala> new Foo(3)                              
<console>:13: error: inferred type arguments [Int] do not conform to class Foo's type parameter bounds [T <: java.lang.Comparable[T]]
       new Foo(3)
       ^
Run Code Online (Sandbox Code Playgroud)

第二个表达式是类型擦除的结果吗?

我将如何定义Foo以便我可以使用Int对其进行参数化,但仍然能够使用其实例变量执行某些排序行为?

mis*_*tor 16

使用视图绑定.

Welcome to Scala version 2.8.0.final (Java HotSpot(TM) Client VM, Java 1.6.0_21).
Type in expressions to have them evaluated.
Type :help for more information.

scala> class Foo[T <% Comparable[T]](val x : T)
defined class Foo

scala> new Foo(3)
res0: Foo[Int] = Foo@9aca82
Run Code Online (Sandbox Code Playgroud)

  • @Collin:`scalac -Xprint:typer myprogram.scala`将显示使用implicits的位置.输入`scalac -Xshow-phases`来查看其他相位. (5认同)
  • 感谢您的链接。这非常有帮助,我有一段时间想知道 &lt;% 是什么意思。因此,如果我理解正确的话, T &lt;% Comparable[T] 其中 T 是 Int,确保存在从 Int 到 Comparable[Int] 的隐式转换,在这种情况下,我猜它会从 Predef.intWrapper 中获取转换到一个 RichInt,它是 Comparable[Int]。我现在明白了。我确实希望 Scala 有一个“调试”模式,可以显示其中一些隐式转换在何处/如何发生。 (2认同)

Dan*_*ral 16

如上所述,问题仍然没有答案(尽管"使用视图边界"解决了问题,这更有用).答案很简单,IntScala 中的一个应该等同int于Java中的Java,它根本不是一个类,因此,甚至不能成为一个Comparable(尽管可以用Java 7中的defender方法解决这个问题......我想知道他们是否会这样做.

使用视图绑定的解决方案在整个Scala中用于解决可以实现某些但不实现的类的问题,因为它不受Scala的控制 - 即Java类.

而且,当然,程序员自己可以使用它来处理来自库和框架的类似内容,或者只是在库周围生成包装器以赋予它Scala-ish的感觉.


Aar*_*rup 7

或者,您可以使用上下文绑定:

class Foo[T: Ordering](val v: T)
Run Code Online (Sandbox Code Playgroud)

要么

class Foo[T: java.util.Comparator](val v: T)
Run Code Online (Sandbox Code Playgroud)

上下文绑定表示一个断言,当调用构造函数时,范围内存在隐式的Ordering [T](或java.util.Comparator [T]),并且等效于添加隐式参数:

class Foo[T](val v: T)(implicit ev: Ordering[T])
Run Code Online (Sandbox Code Playgroud)

这种方法的优点是它允许您根据上下文使用备用顺序:

// by default, new Foo("a", "c", "b").items == List("a", "b", "c")
class Foo[T: Ordering](xs: T*) {
   val items = xs.toList.sorted
}

// with this object in scope, 
// new Foo("a", "c", "b").items == List("c", "b", "a")
implicit val descending = Ordering[String].reverse
Run Code Online (Sandbox Code Playgroud)