我的元问题是“如何清晰地问这个问题?”但也许一个例子可以让它更清晰:
trait Toolbox {
trait Bolt
trait Wrench {
def tighten(b : Bolt)
}
def getWrench : Wrench
def getBolt : Bolt
}
object MetricToolbox extends Toolbox {
...
}
object EnglishToolbox extends Toolbox {
...
}
当然,公制扳手只能拧紧公制螺栓;同上英文工具箱中的工具。我的问题是,如何以类型安全的方式表达,以便不会编译:
MetricToolbox.getWrench tighten EnglishToolbox.getBolt
但以下将:
def doTighten(box : Toolbox) = box.getWrench tighten box.getBolt
我知道这是可能的,因为我听说Martin Odersky昨晚在Scala聚会上用自己的嘴说出来但是在那一刻,我的妻子打电话给我的牢房,我不得不赶紧离开房间。解释了如何。
编辑 didierd指出我的代码是按照书面编写的。他是对的 - 我对细节有点不清楚但确实如此。自然的反向问题是,我如何不这样做?答案非常简单:把这些类放在与主要特征相同的水平上。
trait Nail
trait Hammer {
def pound(n : Nail)
}
trait Toolbox {
trait Bolt
trait Wrench {
def tighten(b : Bolt)
}
def getWrench : Wrench
def getBolt : Bolt
def getNail : Nail
def getHammer : Hammer
}
MetricToolbox.getHammer pound EnglishToolbox.getNail // this DOES compile
答案 0 :(得分:8)
如上所述,它已经有效了。由于Bolt
和Wrench
嵌套在Toolbox
内,因此Bolt
的{{1}}类型意味着tighten
这个确切工具箱的Bolt
,而不是任何工具箱的Bolt
。它们分别是someToolbox.Bolt
,这意味着确切实例Bolt
和someToolBox
的{{1}},这意味着Toolbox#Bolt
类型中定义的Bolt
无论什么是insatance工具箱。所以Toolbox
是所有Toolbox#Bolt
的常见超类型。
此处x.Bolt
没有限定条件意味着Bolt
,this.Bolt
是封闭的工具箱。所以你不能混。