我是scala的初学者,并且我试图将自己的头放在分散的隐式扩展上。
这是我的玩具代码:
class FooList[T](implicit ord: Ordering[T]) {
}
class Human(val score: Int) extends Ordering[Human] {
override def compare(x: Human, y: Human): Int = {
return x.score.compareTo(y.score);
}
}
object Main {
def main(args: Array[String]): Unit = {
val h = new Human(100)
val lst = new FooList[Human]();
}
}
我遇到错误:
diverging implicit expansion for type Ordering[Human]
starting with method comparatorToOrdering in trait LowPriorityOrderingImplicits
not enough arguments for constructor FooList: (implicit ord: Ordering[Human])FooList[Human].
Unspecified value parameter ord.
https://scastie.scala-lang.org/wkSrZ6BMQKW9ZJrsZhlITQ
我会喜欢一个或两个正确方向的指针:)
答案 0 :(得分:4)
“发散”消息在这里有点令人困惑,真正的问题是对类型类如何工作的误解。它应该是这样的:
class FooList[T](implicit ord: Ordering[T]) {
}
case class Human(score: Int)
implicit object HumanOrdering extends Ordering[Human] {
def compare(x: Human, y: Human): Int =
x.score.compareTo(y.score)
}
object Main {
def main(args: Array[String]): Unit = {
val h = new Human(100)
val lst = new FooList[Human]()
}
}
请注意,Human
类只是一种简单的数据类型。有一个单独的implicit object
,它通过扩展Human
来实现Ordering[Human]
对象的排序。
关于类型类的要点是,该行为不是原始类的一部分,而是通过创建适当类型的implicit
值来绑定到该类。这样,您就可以向类中添加多种行为,而不必修改基础类本身。
请注意,如果您想使内容更整洁,可以将此implicit object
放在类对象中:
object Human {
implicit object HumanOrdering extends Ordering[Human] {
def compare(x: Human, y: Human): Int =
x.score.compareTo(y.score)
}
}