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开始
我哪里错了?
首先,Ordering类似于Comparator,不是Comparable.斯卡拉相当于Comparable是Ordered.接下来,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以其他答案描述的方式使用.
这应该是一个上下文绑定,如下所示.
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)
| 归档时间: |
|
| 查看次数: |
652 次 |
| 最近记录: |