2012-06-01 73 views
3

我在试图制作一个允许用户将多个处理器链接在一起的系统。我遇到的困难是每个处理器实际上都有两位关心的信息,我希望这些信息以类型安全的方式处理。我煮下来到这个问题:在scala中实例化特征

考虑:

//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 = { 新与ThingThatImMixedInWithLikeXOrY {}甲 } }

每个处理器需要返回一个匿名类包含:1)已知的处理器2 A型)混入的类型。

我的第一个尝试是使用仿制药,是这样的:

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 
... 

很显然,我已经运行到一个目录的问题:

  1. 我不能让一个泛型类从类型参数延伸

  2. 我不能通过通用参数实例化我的匿名类

  3. 我无法定义特征中函数的返回类型,因为我 直到它与某物混合之前才知道该类型。

我有点小白,当谈到Scala和我得到的,我在完全错误的方式去了解这个感觉,也许我应该使用implicits和CanBuildFrom模式。任何帮助将不胜感激。

干杯

+2

您最大限度地减少了问题并使其非常抽象。在某些情况下,这可能是一件好事,但我认为在这种特殊情况下,如果您会向我们描述具体问题和您想要存档的目标,那将会更有帮助。据我所知,在这个问题中,你正在描述我们还不知道的问题的(破解)解决方案。如果你愿意与我们分享,可能我们会为你目前面临的问题提出另一个/更好的/有效的解决方案...... – tenshi

+0

好的,这里有。我想要一个语法,以便我可以执行诸如 dataSource.map(...)。filter(...) 其中dataSource是我自己的一种流。问题是,我想对其执行其他操作,而不是转换,而是修改计算的执行方式。 例如,我可能想要做datasource.asParallel.filter(...)。asSequential。 这是一个稍微做作的例子,但你可以看到我有两组操作。 asParallel的返回类型需要是暴露asSequential操作的东西。 –

回答

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)) 

不能被避免因为它将要求包装成参数化的特征e scala继承了多次不同参数的特征,这是被着名类型擦除禁止的多次

相关问题