我正在学习 Scala 以便将其用于项目。
我想要更深入了解的一件事是类型系统,因为它是我以前在其他项目中从未使用过的东西。
假设我已经设置了以下代码:
// priority implicits
sealed trait Stringifier[T] {
def stringify(lst: List[T]): String
}
trait Int_Stringifier {
implicit object IntStringifier extends Stringifier[Int] {
def stringify(lst: List[Int]): String = lst.toString()
}
}
object Double_Stringifier extends Int_Stringifier {
implicit object DoubleStringifier extends Stringifier[Double] {
def stringify(lst: List[Double]): String = lst.toString()
}
}
import Double_Stringifier._
object Example extends App {
trait Animal[T0] {
def incrementAge(): Animal[T0]
}
case class Food[T0: Stringifier]() {
def getCalories = 100
}
case class Dog[T0: Stringifier]
(age: Int = 0, food: Food[T0] = Food()) extends Animal[String] {
def incrementAge(): Dog[T0] = this.copy(age = age + 1)
}
}
所以在这个例子中,有一个类型错误:
ambiguous implicit values:
[error] both object DoubleStringifier in object Double_Stringifier of type Double_Stringifier.DoubleStringifier.type
[error] and value evidence$2 of type Stringifier[T0]
[error] match expected type Stringifier[T0]
[error] (age: Int = 0, food: Food[T0] = Food()) extends Animal[String]
好,可以。但是如果我删除上下文绑定,这段代码就会编译。即,如果我将 '''Dog''' 的代码更改为:
case class Dog[T0]
(age: Int = 0, food: Food[T0] = Food()) extends Animal[String] {
def incrementAge(): Dog[T0] = this.copy(age = age + 1)
}
现在我假设这也不会编译,因为这种类型更通用,更模棱两可,但确实如此。
这里发生了什么?我知道当我将上下文绑定时,编译器不知道它是 double 还是 int。但是为什么还要编译一个更通用的类型呢?当然,如果没有上下文绑定,我可能有一个 Dog[String] 等,这也会使编译器感到困惑。
从这个答案:“上下文绑定描述了一个隐式值,而不是视图绑定的隐式转换。它用于声明对于某些类型 A,有一个 B[A] 类型的隐式值可用”