scala - 使用类型成员作为自身类型

标签 scala self-type type-projection

我遇到了应与类型成员相对应的递归 self 类型的问题:

trait Elem { me =>
  type Peer

  import me.{Peer => Peer0}

  type This <: Elem { type Peer = Peer0 }

  def mkCopy(): This
}

现在我想定义一个方便的特征:

trait ImmutableImpl extends Elem {
  _ : This =>

  def mkCopy(): This = this
}

这不起作用,因为“错误:未找到:键入此” :(

下一次尝试:

trait ImmutableImpl[Repr] extends Elem {
  _ : Repr =>

  type This = Repr

  def mkCopy(): This = this
}

此操作失败,并显示“错误:覆盖类型此...此类型具有不兼容的类型”

我只能做这种令人厌恶的事:

trait ImmutableImpl[Peer0, Repr <: Elem { type Peer = Peer0 }] extends Elem {
  _ : Repr =>

  type Peer = Peer0
  type This = Repr

  override def mkCopy(): This = this
}

class IntElem extends ImmutableImpl[Int, IntElem]

在实际情况中,我有更多的类型成员,因此这使得最后一种方法毫无用处,因为每次手动实现 mkCopy 都是更多的样板。

有什么想法吗?

最佳答案

似乎类型参数更适合于此。

trait Elem[A] { me: A =>
    def mkCopy(): A = this
}

scala> class Z extends Elem[Z]

scala> (new Z).mkCopy()
res0: Z = Z@3003a3a3

我认为问题在于类型成员不在 self 类型声明的范围内,而解决这个问题的方法是使用与另一个特征绑定(bind)的结构类型。但为什么不去掉中间人,只在 Elem 上使用类型参数,并要求它与参数的类型相同。

关于scala - 使用类型成员作为自身类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28611656/

相关文章:

scala - 无法证明 Null < :< T

scala - 如何与 Actor 一起使用 Tinkerpop

scala - 具有更高种类类型的类的自类型注释

scala - 即使在使用类型投影后为 Either 声明 Functor 时出现编译错误

Scala - 创建基本的动态函数解析器

scala - Scala:使用具体实例的返回类型实现方法

scala - 与 '' this'' 没有类型/差异的显式自引用

scala - 引用类型参数的抽象类型成员

具有更高级类型的 Scala 类型投影

scala - Scala 3 中的类型模式匹配和推理错误