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)
^
第二个表达式是类型擦除的结果吗?
我如何定义Foo以便我可以使用Int对其进行参数化,但仍能够使用其实例变量执行某些排序行为?
答案 0 :(得分:16)
使用view bound。
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
答案 1 :(得分:16)
如上所述,问题仍然没有答案(尽管“使用视图边界”解决了问题,这更有用)。答案很简单,Scala中的Int
应该等同于Java中的int
,它根本不是一个类,因此甚至不能是Comparable
(虽然可以使用defender方法在Java 7中解决...我想知道他们是否会这样做。
使用视图绑定的解决方案在整个Scala中用于解决可以实现某些但不能实现某些内容的类的问题,因为它不受Scala的控制 - 即Java类。
当然,程序员自己可以使用它来处理来自库和框架的类似内容,或者只是为了生成一个Scala-ish的感觉而在库周围生成包装器。
答案 2 :(得分:7)
或者,您可以使用context bound:
class Foo[T: Ordering](val v: T)
或
class Foo[T: java.util.Comparator](val v: T)
上下文绑定表示一个断言,当调用构造函数时,范围内存在隐式的Ordering [T](或java.util.Comparator [T]),并且等效于添加隐式参数:
class Foo[T](val v: T)(implicit ev: Ordering[T])
这种方法的优点是它允许您根据上下文使用备用排序:
// 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