现在我很困惑。我对Scala很新,已经使用了几个星期,我想我已经熟悉了它,但我仍然坚持看似简单的以下情况。
我找不到与此Java声明等效的Scala:
public static <T extends Comparable<T>> List<T> myMethod(List<T> values) {
// ...
final List<T> sorted = new ArrayList<T>(values);
Collections.sort(sorted);
// ...
}
我认为以下情况会这样做:
def myMethod[A >: Ordering[A]](values: Seq[A]): Seq[A] = {
// ...
val sorted = values.sorted
//
}
但是,我收到以下错误:
错误:涉及类型A的非法循环引用
错误:类型scala.math.Ordering [A]的隐式扩展分歧 从对象排序中的方法Tuple9开始
我哪里错了?
答案 0 :(得分:7)
首先,Ordering
类似于Comparator
,而不是Comparable
。相当于Comparable
的Scala是Ordered
。接下来,extends
等效为<:
,而不是>:
。后者相当于super
- T super COmparable<T>
,这不是您想要的。因此,在这两个修复程序中,您的代码应如下所示:
def myMethod[A <: Ordered[A]](values: Seq[A]): Seq[A] = {
// ...
val sorted = values.sorted
//
}
但是,这不适用于Seq[Int]
,例如,因为Int
不会扩展Ordered
- 就像Java的int
不会扩展{{1} (或其他任何东西,因为它不是一个类)。
Scala有一个解决方法 - 从某些类到Comparable
类的隐式转换。但是,要使用它,您需要使用view bound,这将使代码看起来像这样:
Ordered
请参阅def myMethod[A <% Ordered[A]](values: Seq[A]): Seq[A] = {
// ...
val sorted = values.sorted
//
}
而不是<%
?这就是观点。
现在,Scala圈子中的当前首选项是使用上下文边界而不是视图边界,因为它们更灵活。这意味着以其他答案描述的方式使用<:
。
答案 1 :(得分:5)
这应该是一个上下文绑定,如下所示。
scala> def myMethod[A : Ordering](values: Seq[A]): Seq[A] = values.sorted
myMethod: [A](values: Seq[A])(implicit evidence$1: Ordering[A])Seq[A]