返回两个值中的第一个的通用方法

Lui*_*hys 7 generics scala

我需要一个方法来返回两个有序值中的第一个.我试过了:

def first[T <: Ordered[T]](a: T, b: T) = {
  a compare b match {
    case -1 | 0 => a
    case 1      => b
  }
}
Run Code Online (Sandbox Code Playgroud)

但得到

scala> first(3,4)
<console>:9: error: inferred type arguments [Int] do not conform to method first's 
type parameter bounds [T <: Ordered[T]]
       first(3,4)
       ^
Run Code Online (Sandbox Code Playgroud)

我想这是因为Int需要转换为a RichInt,Ordered[Int]而不是a Ordered[RichInt].接下来是什么?

ten*_*shi 8

您可以使用类型类Ordering和上下文绑定:

def first[T : Ordering](a: T, b: T) = {
  implicitly[Ordering[T]].compare(a, b) match {
    case -1 | 0 => a
    case 1      => b
  }
}
Run Code Online (Sandbox Code Playgroud)

更新

如果你这个代码可以进一步简化import scala.math.Ordered._.Companion对象Ordered具有orderingToOrdered隐式转换,因此所有内容Ordering也将被视为Ordered:

import scala.math.Ordered._

def first[T : Ordering](a: T, b: T) = if (a <= b) a else b
Run Code Online (Sandbox Code Playgroud)


Kip*_*ros 8

我想你正在寻找一个视界

def first[T <% Ordered[T]](a: T, b: T) = {
  a compare b match {
  case -1 | 0 => a
  case 1      => b
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,

scala> first(3, 2)
res3: Int = 2
Run Code Online (Sandbox Code Playgroud)

在幕后,结合的视图将编译成转换类型的隐式参数TOrdered[T].Daniel Sobral的回答有一个很好的解释:什么是Scala上下文和视图边界?

编辑.在Scala 2.8中引入,Ordering可能是进行比较的首选方法,但我找不到任何明确的指导.我猜想Ordered具有与Java兼容的优势Comparable,正如其他人所指出的那样,在Ordered和之间存在隐式转换Ordering.