[英]evaluation of an abstract type member
为什么这段代码不能编译? 在 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()
当使用类型成员而不是类型参数进行参数化时,您必须在要求类型 class 实例时提供类型细化,否则您只要求 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
通常你会创建依赖类型的方法,然后你可以避免方法定义中的类型细化(但它仍然需要定义类型 class 实例)
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 章,使用类型和隐含”进行学习,特别是其中提到的部分
...如果我们将返回类型定义为
Second[L]
,则Out
类型成员将从返回类型中删除,并且类型 class 将无法正常工作。
不,没有办法。
想想如果你用另一个定义type Size = Int
的SizeOfType[Unit]
类型的隐式值调用test
会发生什么。
或者换一种说法,方法test
只能根据SizeOfType
的 trait 定义来推断类型,而不是根据一个实际的隐含值内容。
但是,您可以将test
定义为返回类型ev.Size
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.