我有一个简单的示例trait,它具有一些来自Ordered的泛型类型的值。虽然我找不到“无法找到参数ord的隐含值:scala.math.Ordering [T]”,但我找不到任何实际使用该值的方法。这是代码:
trait Example[T <: Ordered[_]] {
val key: T
def before(that: Example[T]): Boolean = (key < that.key)
}
为什么这不能编译?
答案 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) }
}
我们将根据此定义进行思考 - 如果key
为Ordered[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]
存在(特征不能有上下文或视图绑定,所以我创建了抽象类)
有意义吗?如果你发现我的逻辑存在缺陷 - 请评论! (我会很感激)