鉴于:
case class Person(name: String)
Run Code Online (Sandbox Code Playgroud)
并尝试做:
scala> List(Person("Tom"), Person("Bob")).sorted
Run Code Online (Sandbox Code Playgroud)
导致对失踪订购的投诉.
<console>:8: error: could not find implicit value for parameter ord: Ordering[Person]
List(Person("Tom"), Person("Bob")).sorted
Run Code Online (Sandbox Code Playgroud)
不过这个:
case class Person(name: String) extends Ordered[Person] {
def compare(that: Person) = this.name compare that.name }
Run Code Online (Sandbox Code Playgroud)
按预期工作正常:
scala> List(Person("Tom"), Person("Bob")).sorted
res12: List[Person] = List(Person(Bob), Person(Tom))
Run Code Online (Sandbox Code Playgroud)
虽然没有涉及订购或暗示.
问题1:这里发生了什么?(我的钱是隐含的......)
但是,考虑到上述事实,这个事实:
scala> Person("Tom") > Person("Bob")
res15: Boolean = true
Run Code Online (Sandbox Code Playgroud)
工作,这也是:
scala> List(Some(2), None, Some(1)).sorted
Run Code Online (Sandbox Code Playgroud)
开箱即用:
res13: List[Option[Int]] = List(None, Some(1), Some(2))
Run Code Online (Sandbox Code Playgroud)
我希望这个:
scala> Some(2) > Some(1)
Run Code Online (Sandbox Code Playgroud)
也会有效,但不会:
<console>:6: error: value > is not a member of Some[Int]
Some(2) > Some(1)
Run Code Online (Sandbox Code Playgroud)
问题2:为什么不,我怎样才能让它发挥作用?
psp*_*psp 29
如果您安装稍微过于神奇的默认范围内的奖励,则可以比较以下选项:
scala> import scala.math.Ordering.Implicits._
import scala.math.Ordering.Implicits._
scala> def cmpSome[T: Ordering](x: Option[T], y: Option[T]) = x < y
cmpSome: [T](x: Option[T], y: Option[T])(implicit evidence$1: Ordering[T])Boolean
Run Code Online (Sandbox Code Playgroud)
导入使用中缀操作向您提供从Ordering到类的隐式,这样就可以在没有其他导入的情况下获得Ordering.
Mor*_*itz 10
关于你的第一个问题:Ordered[T]延伸Comparable[T].的Ordering同伴对象提供的隐式Ordering[T]为可被转换成一个任意值Comparable[T]:
implicit def ordered[A <% Comparable[A]]: Ordering[A]
Run Code Online (Sandbox Code Playgroud)
没有隐式转换A : Ordering => Ordered[A]- 这就是为什么Some(1) > Some(2)不起作用的原因.
如果定义这样的转换是一个好主意是值得怀疑的,因为你可能最终将对象包装到Ordered实例中然后再创建一个Ordering(等等......).更糟糕的是:您可以在范围内创建Ordered具有不同Ordering实例的两个实例,这当然不是您想要的.