【问题标题】:What is more Scala idiomatic: trait TraitA extends TraitB or trait TraitA { self: TraitB => }什么是 Scala 惯用的: trait Trait extends Trait 或 trait TraitS { self: TraitB => }
【发布时间】:2011-08-30 22:07:08
【问题描述】:

除了继承方面,以下类模板是否有区别:

1| trait TraitA extends TraitB

2| trait TraitA { self: TraitB => }

我想在TraitATraitB 之间划分职责,但如果没有后者,前者就无法运作。

您将如何表达这种意图? 对我来说,解决方案 [2] 将是更自然的方法。但是,我不想让实施者承担混入任何需要混入的负担。

【问题讨论】:

标签: scala inheritance traits self-type


【解决方案1】:

我的偏好通常是 [1],因为正如您所说,实现者没有负担混入 TraitB 的(子类型)。如果出于某种原因希望继承TraitB 中的具体实现并强制实现者在TraitB 的子类型中做出选择,那么[2] 可能更可取。尽管如此,[1] 还是一样灵活。

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

// Here, Matrix cannot extend type parameter Repr
trait Matrix[+Repr <: Matrix[Repr]] { self: Repr =>
  ...
}

更新。这是另一个小区别,

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

有点烦人 可选限制不能将A 用作B,即使该类型已合并。

【讨论】:

  • 谈到您的更新。我认为“小烦恼”对于让人们表达A“与”“合作”但同时“不是”B 非常有用。对我来说,这有点像私有继承和公共继承。
  • 从历史上看,self-type annotation 的动机是第一个区别——至少,这就是 Odersky&Zenger 的论文 Scalable Component Abstractions 中这个特性的动机(你可以如果有兴趣,请在 Google Scholar 上查找)。
猜你喜欢
  • 2015-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多