繁体   English   中英

抽象类型成员的评估

[英]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 = IntSizeOfType[Unit]类型的隐式值调用test会发生什么。

或者换一种说法,方法test只能根据SizeOfType的 trait 定义来推断类型,而不是根据一个实际的隐含值内容。

但是,您可以将test定义为返回类型ev.Size

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM