我正在尝试建立一个允许用户将多个处理器链接在一起的系统。我遇到的困难是每个处理器实际上都有两个它关心的信息,我希望这些信息以类型安全的方式处理。我把它归结为这个问题:
假设:
//First family of stuff
trait A {
def doA {}
}
trait B {
def doB {}
}
//Second family of stuff
trait X {
def doX {}
}
trait Y {
def doY {}
}
我可以将两个家庭的元素组合成4种口味:
var f = new A with X {}
f.doA
d.doX
var g = new A with Y {}
//...
大。问题是我希望每个函数(doA等)返回两种类型的组合,以便我可以将东西链接在一起。基本上我想做: 特质A { def doThing = { 新的A与ThingThatImMixedInWithLikeXOrY {} } }
每个处理器都需要返回一个匿名类,其中包括1)处理器已知的类型2)与之混合的类型。
我的第一个尝试是使用泛型,类似这样:
trait A {
this : {def makeWithT[TOther]} =>
def doA = makeWithT[B]
}
trait B {
this : {def makeWithT[TOther]} =>
def doB = makeWithT[A]
}
trait X {
this : {def makeWithS[TOther]} =>
def doX = makeWithT[Y]
}
trait Y {
this : {def makeWithS[TOther]} =>
def doY = makeWithT[Y]
}
class Foo[T, S] extends S with T {
def makeWithT[OtherT] = new T with OtherT
def makeWithS[OtherT] = new S with OtherT
}
var f = new Foo[A, X]
f.doA.doB
f.doX.doA
f.doX.doY
...
显然,我遇到了一系列问题:
我不能创建一个从类型参数
我无法通过通用参数
我无法定义特征中函数的返回类型,因为我 不知道这种类型,直到它与某种东西混合在一起。
对于scala来说,我有点像菜鸟,我觉得我会以完全错误的方式解决这个问题,也许我应该使用implicits和CanBuildFrom模式。任何帮助将不胜感激。
干杯
答案 0 :(得分:1)
可堆叠处理器最着名的解决方案是可堆叠特征
http://www.artima.com/scalazine/articles/stackable_trait_pattern.html
trait StackableRoot {
def StackablePass (x:Int) : x
}
trait StackableDouble extends StackableRoot {
def internalPass (x:Int) = 2*x
abstract override def StackablePass(x:Int) = super.StackablePass(internalPass(x))
}
trait StackableIncrement extends StackableRoot {
def internalPass (x:Int) = x+1
abstract override def StackablePass(x:Int) = super.StackablePass(internalPass(x))
}
有一些带有
的样板 abstract override def StackablePass(x:Int) = super.StackablePass(internalPass(x))
通过打包到参数化特征无法避免,因为它需要scala继承一些具有不同参数的特征,这是多次被着名类型擦除所禁止的