订购的参数化方法?

sca*_*1sk 3 scala variance type-parameter

现在我很困惑.我是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);
  // ...
}
Run Code Online (Sandbox Code Playgroud)

我以为会有以下情况:

def myMethod[A >: Ordering[A]](values: Seq[A]): Seq[A] = {
  // ...
  val sorted = values.sorted
  //
}
Run Code Online (Sandbox Code Playgroud)

但是,我收到以下错误:

错误:涉及类型A的非法循环引用

错误:类型scala.math.Ordering [A]的分散隐式扩展从对象Ordering中的方法Tuple9开始

我哪里错了?

Dan*_*ral 7

首先,Ordering类似于Comparator,不是Comparable.斯卡拉相当于ComparableOrdered.接下来,extends等同于<:,而不是>:.后者相当于super- T super COmparable<T>,这不是你想要的.因此,通过这两个修复程序,您的代码应如下所示:

def myMethod[A <: Ordered[A]](values: Seq[A]): Seq[A] = {
  // ...
  val sorted = values.sorted
  //
}
Run Code Online (Sandbox Code Playgroud)

但是,这不适用于Seq[Int],例如,因为Int没有扩展Ordered- 就像Java int没有扩展Comparable(或其他任何东西,因为它不是一个类).

Scala有一个解决方法 - 从某些类到Ordered类的隐式转换.但是,要使用它,您需要使用视图绑定,这将使代码看起来像这样:

def myMethod[A <% Ordered[A]](values: Seq[A]): Seq[A] = {
  // ...
  val sorted = values.sorted
  //
}
Run Code Online (Sandbox Code Playgroud)

<%而不是<:?那就是视界.

现在,Scala圈子中的当前首选项是使用上下文边界而不是视图边界,因为它们更灵活.这意味着Ordering以其他答案描述的方式使用.


mis*_*tor 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]
Run Code Online (Sandbox Code Playgroud)