Parameterized method with Ordering?
Now I am confused. I am quite new on Scala, having worked with it for a few weeks, I think I am getting familiar with it, but I am stuck on the appar开发者_如何学Pythonently trivial following case.
I cannot find the Scala equivalent to this Java declaration :
public static <T extends Comparable<T>> List<T> myMethod(List<T> values) {
// ...
final List<T> sorted = new ArrayList<T>(values);
Collections.sort(sorted);
// ...
}
I thought the following would do :
def myMethod[A >: Ordering[A]](values: Seq[A]): Seq[A] = {
// ...
val sorted = values.sorted
//
}
However, I get the following errors:
error: illegal cyclic reference involving type A
error: diverging implicit expansion for type scala.math.Ordering[A] starting with method Tuple9 in object Ordering
Where am I wrong?
First of all, Ordering
is akin to Comparator
, not Comparable
. The Scala equivalent to Comparable
is Ordered
. Next, extends
equivalent is <:
, not >:
. The latter is equivalent to super
-- T super COmparable<T>
, which is not what you want. So, with both these fixes in, your code should look like this:
def myMethod[A <: Ordered[A]](values: Seq[A]): Seq[A] = {
// ...
val sorted = values.sorted
//
}
However, this won't work for Seq[Int]
, for instance, since Int
does not extend Ordered
-- just like Java's int
does not extend Comparable
(or anything else, since it is not a class).
Scala has a work-around for that -- an implicit conversion from certain classes to an Ordered
class. To use that, however, you need to use a view bound, which would make the code look like this:
def myMethod[A <% Ordered[A]](values: Seq[A]): Seq[A] = {
// ...
val sorted = values.sorted
//
}
See <%
instead of <:
? That's the view bound.
Now, the current preference in Scala circles is to use context bounds instead of view bounds, as they are more flexible. That would mean using Ordering
, in the manner described by the other answers.
That should be a context bound, as shown below.
scala> def myMethod[A : Ordering](values: Seq[A]): Seq[A] = values.sorted
myMethod: [A](values: Seq[A])(implicit evidence$1: Ordering[A])Seq[A]
精彩评论