什么是Scala惯用语:特质TraitA扩展TraitB或特质TraitA {self:TraitB =>}

Tim*_*ske 19 inheritance scala traits self-type

除了继承方面,以下类模板之间是否存在差异:

1| trait TraitA extends TraitB

2| trait TraitA { self: TraitB => }
Run Code Online (Sandbox Code Playgroud)

我想在两者之间分配责任TraitA,TraitB但如果没有后者,前者就无法运作.

你会如何表达这个意图?对我而言,解决方案[2]将是更自然的方法.但是,我不想把实施者的负担混合在一起需要混合的东西.

Kip*_*ros 16

我的偏好通常是[1]因为正如你所说的那样,实现者没有负担混合(子类型)TraitB.如果由于某种原因,希望继承具体实现TraitB并迫使实现者在子类型中做出选择,那么[2]也许是可取的TraitB.尽管如此,[1]同样灵活.

我倾向于仅在必要时使用[2],例如当类型不是已知的类或特征时,

// Here, Matrix cannot extend type parameter Repr
trait Matrix[+Repr <: Matrix[Repr]] { self: Repr =>
  ...
}
Run Code Online (Sandbox Code Playgroud)

更新.这是另一个细微差别,

trait B
trait A { self: B => }
def g(ab: A): B = ab // Type mismatch: found A, required B
Run Code Online (Sandbox Code Playgroud)

它的 有点烦人 一个可选的限制,即使该类型被合并,也不能A用作a B.

  • 谈谈你的更新.我认为"小烦恼"对于让一个人表示"A"与"但同时"合作并不是"一个`B"非常有用.对我来说,这有点像私人与公共继承. (2认同)