为什么这段代码无法编译?在 Scala 2.13.6 上测试。有没有办法让 scalac 知道 SizeOfType[Unit]#Size
实际上是 Short
?
trait SizeOfType[T] {
type Size
def getSize(): Size
}
object SizeOfType {
implicit def unit: SizeOfType[Unit] = new SizeOfType[Unit] {
type Size = Short
def getSize(): Short = 0
}
def test(implicit ev: SizeOfType[Unit]): Short = ev.getSize()
}
[error] type mismatch;
[error] found : ev.Size
[error] required: Short
[error] def test(implicit ev: SizeOfType[Unit]): Short = ev.getSize()
最佳答案
当使用类型成员而不是类型参数进行参数化时,您必须在请求类型类实例时提供类型细化,否则您只是在向 Scala 请求
SizeOfType[Unit]
而不是预期的
SizeOfType[Unit] { type Size = Short }
类似的东西
implicit val unit: SizeOfType[Unit] { type Size = Short } =
new SizeOfType[Unit] {
type Size = Short
def getSize(): Short = 0
}
def test(implicit ev: SizeOfType[Unit] { type Size = Short }): Short = ev.getSize()
val x: Short = test // ok
通常你会创建依赖类型的方法,然后你可以避免在方法定义中进行类型细化(但类型类实例的定义仍然需要它)
implicit val unit: SizeOfType[Unit] { type Size = Short } = ???
def test(implicit ev: SizeOfType[Unit]): ev.Size = ev.getSize()
val x: Short = test // ok
我建议学习 underscoreio/shapeless-guide 的“第 4 章,使用类型和隐式” ,特别是提到的部分
...If we define the return type as
Second[L]
, theOut
type member will be erased from the return type and the type class will not work correctly.
关于scala - 评估抽象类型成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67852956/