为什么我得到“找不到参数ord的隐含值:scala.math.Ordering [T]”

时间:2011-01-26 20:02:10

标签: scala

我有一个简单的示例trait,它具有一些来自Ordered的泛型类型的值。虽然我找不到“无法找到参数ord的隐含值:scala.math.Ordering [T]”,但我找不到任何实际使用该值的方法。这是代码:

trait Example[T <: Ordered[_]] {
  val key: T

  def before(that: Example[T]): Boolean = (key < that.key)    
}

为什么这不能编译?

2 个答案:

答案 0 :(得分:6)

我认为它应该是

trait Example[T <: Ordered[T]] {

答案 1 :(得分:1)

我相信,我没有编译,因为你说T应该在任何类型上订购。我们可以编写一个这样的等价特征(请纠正我,如果我错了 - 我不确定它是否可以被认为是等价的,但至少你会从编译器收到同样的错误):

trait Example1[A, T <: Ordered[A]] {
    val key: T

    def before(that: Example1[A, T]): Boolean = (key < that.key)
}

如果您查看Ordered特质定义,您会发现类似的内容:

trait Ordered[A] extends java.lang.Comparable[A] {
  ...

  def <  (that: A): Boolean = (this compare that) <  0
  ...
}

object Ordered {  
  /** Lens from Ordering[T] to Ordered[T] */
  implicit def orderingToOrdered[T](x: T)(implicit ord: Ordering[T]): Ordered[T] = 
    new Ordered[T] { def compare(that: T): Int = ord.compare(x, that) }
}

我们将根据此定义进行思考 - 如果keyOrdered[A]而非that.key应为A类型(根据<方法签名)。因此,编译器实际上无法在Ordered[A]或其他字T上使用它。如果我没有误会它试图找到一些Ordering[T](根据伴随对象中的隐式定义),可以作为最后的手段(但它失败了)。

因此,如果您要定义类型参数T,如T <: Ordered[T],则会编译。

作为此问题的另一种解决方案,您可以使用上下文绑定,如下例所示:

abstract class Example[T: Ordering] {
  val key: T
  val ord = implicitly[Ordering[T]]
  import Ordered._

  def before(that: Example[T]): Boolean = key < that.key
}

var one = new Example[Int] {val key = 1}
var two = new Example[Int] {val key = 2}

println(one.before(two)) // prints: true
println(two.before(one)) // prints: false

在这种情况下,实际上会使用隐式转换,因为我们有证据表明Ordering[T]存在(特征不能有上下文或视图绑定,所以我创建了抽象类)

有意义吗?如果你发现我的逻辑存在缺陷 - 请评论! (我会很感激)