【发布时间】:2016-07-02 12:31:51
【问题描述】:
我正在用 Scala 设计一个简单的数据处理管道。它涉及PipelineStage,其中transform 一些StageOutput 变成另一个StageOutput。 Pipeline 是一系列 PipelineStage 的包装器,它需要一般地访问它们的所有 transform 方法。
但是我遇到了麻烦,因为我提出的两种解决方案基本上都不起作用......第一个依赖于以非多态方式实现的抽象多态方法(不编译)和第二个依赖于能够使用Seq[AbstractTrait],其中AbstractTrait 是多态的,这对编译器来说再次毫无意义。如下图...
场景 1. 使 transform 方法具有多态性。
abstract trait PipelineStage {
def transform[A <: StageOutput, B <: StageOutput](in: A): B
}
class PipelineStage2 extends PipelineStage {
def transform(in: StageOutput1): StageOutput2
}
class Pipeline {
def stages: Seq[PipelineStage]
}
这里Pipeline 编译没有问题,但是阶段不会编译,因为他们的transform 方法的签名虽然他们“尊重”抽象签名的多态性,但它们本身实际上并不是多态的,所以不要就编译器而言匹配。
场景 2. 使 PipelineStage 特征本身具有多态性。
abstract trait PipelineStage[A <: StageOutput, B <: StageOutput] {
def transform(in: A): B
}
class PipelineStage2 extends PipelineStage[StageOutput1, StageOutput2] {
def transform(in: StageOutput1): StageOutput2
}
class Pipeline {
def stages: Seq[PipelineStage]
}
这解决了PipelineStages 的问题,他们编译没有问题,并且他们的转换方法可以自己正常工作。但是,它们现在在技术上没有实现相同的特征,所以 Pipeline 无法编译,因为 Seq[PipelineStage] 现在没有意义了......
是否有既定的模式来实现没有多态性的多态抽象方法,或者引用实现相同抽象多态特征的一系列类?我的感觉是不,我可能以错误的方式处理这个问题,但也许我在某个地方遗漏了一个句法技巧。谢谢。
【问题讨论】:
-
尝试填写
Pipeline方法的主体,假设您可以通过某种方式编译它,并且可以访问def stages: Seq[PipelineStage]。显示您计划如何使用该功能。
标签: scala functional-programming polymorphism