隐式转换的类型推断
Type inference of implicit conversions
考虑这段代码:
sealed trait Data
case class StringData(string: String) extends Data
case class IntData(int: Int) extends Data
trait Reader[A] {
def read(data: Data): A
}
implicit val stringReader: Reader[String] = {
case StringData(string) => string
case _ => sys.error("not a string")
}
implicit val intReader: Reader[Int] = {
case IntData(int) => int
case _ => sys.error("not an int")
}
在此范围内,我想编写一个隐式方法,将 Data
值静默转换为它们的 "real" Scala 值。
implicit def fromData[A: Reader](data: Data): A =
implicitly[Reader[A]].read(data)
但是,这段代码无法编译:
val str: String = StringData("foo")
val int: Int = IntData(420)
错误是类型不匹配。隐式的标准调试方法显示无法从 fromData
推断出 A
(所有隐式 Reader
均显示为适用)。
为方便起见,this is a link to a scastie of the code. In this other scastie 提供了一个类似但不同的工作代码段。
我的问题:这是怎么回事?
对您的 Data
class 以及您的 reader 隐式转换进行如下更改允许编译代码。
import scala.language.implicitConversions
sealed trait Data[A]
case class StringData(string: String) extends Data[String]
case class IntData(int: Int) extends Data[Int]
trait Reader[A] {
def read(data: Data[A]): A
}
implicit val stringReader: Reader[String] = {
case StringData(string) => string
case _ => sys.error("not a string")
}
implicit val intReader: Reader[Int] = {
case IntData(int) => int
case _ => sys.error("not an int")
}
implicit def fromData[A](data: Data[A])(implicit ev: Reader[A]): A = ev.read(data)
val str: String = StringData("foo")
val int: Int = IntData(420)
您需要输入数据,以便编译器可以根据 Data
的类型参数推断出应该使用哪个 Reader。另请注意,如果您未定义隐式 Reader,则以下内容不会编译。
case class DoubleData(d: Double) extends Data[Double]
// Fails compilation because no implicit Reader exists.
val d: Double = DoubleData(5d)
考虑这段代码:
sealed trait Data
case class StringData(string: String) extends Data
case class IntData(int: Int) extends Data
trait Reader[A] {
def read(data: Data): A
}
implicit val stringReader: Reader[String] = {
case StringData(string) => string
case _ => sys.error("not a string")
}
implicit val intReader: Reader[Int] = {
case IntData(int) => int
case _ => sys.error("not an int")
}
在此范围内,我想编写一个隐式方法,将 Data
值静默转换为它们的 "real" Scala 值。
implicit def fromData[A: Reader](data: Data): A =
implicitly[Reader[A]].read(data)
但是,这段代码无法编译:
val str: String = StringData("foo")
val int: Int = IntData(420)
错误是类型不匹配。隐式的标准调试方法显示无法从 fromData
推断出 A
(所有隐式 Reader
均显示为适用)。
为方便起见,this is a link to a scastie of the code. In this other scastie 提供了一个类似但不同的工作代码段。
我的问题:这是怎么回事?
对您的 Data
class 以及您的 reader 隐式转换进行如下更改允许编译代码。
import scala.language.implicitConversions
sealed trait Data[A]
case class StringData(string: String) extends Data[String]
case class IntData(int: Int) extends Data[Int]
trait Reader[A] {
def read(data: Data[A]): A
}
implicit val stringReader: Reader[String] = {
case StringData(string) => string
case _ => sys.error("not a string")
}
implicit val intReader: Reader[Int] = {
case IntData(int) => int
case _ => sys.error("not an int")
}
implicit def fromData[A](data: Data[A])(implicit ev: Reader[A]): A = ev.read(data)
val str: String = StringData("foo")
val int: Int = IntData(420)
您需要输入数据,以便编译器可以根据 Data
的类型参数推断出应该使用哪个 Reader。另请注意,如果您未定义隐式 Reader,则以下内容不会编译。
case class DoubleData(d: Double) extends Data[Double]
// Fails compilation because no implicit Reader exists.
val d: Double = DoubleData(5d)