我遇到了一个与一个类型成员对应的递归自我类型的问题:
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
都需要更多的锅炉板。
有什么想法吗?
答案 0 :(得分:1)
似乎类型参数更适合这种情况。
trait Elem[A] { me: A =>
def mkCopy(): A = this
}
scala> class Z extends Elem[Z]
scala> (new Z).mkCopy()
res0: Z = Z@3003a3a3
我认为问题是类型成员不在自我类型声明的范围内,而你解决这个问题的方法是使用与另一个特征绑定的结构类型。但是为什么不切断中间人,只使用Elem
上的类型参数和自我类型,要求它与参数的类型相同。
答案 1 :(得分:1)
我的解决方法是放宽This
上的细化,因为我的API最终似乎不需要这样做:
trait Elem { me =>
type Peer
// import me.{Peer => Peer0}
type This <: Elem // { type Peer = Peer0 }
def mkCopy(): This
}
trait ImmutableImpl[Repr <: Elem] extends Elem {
_ : Repr =>
override type This = Repr
def mkCopy(): This = this
}
class IntElem extends ImmutableImpl[IntElem] {
type Peer = Int
}