2016-07-02 8 views
2

私はScalaで単純なデータ処理パイプラインを設計しています。これは、PipelineStageのものであり、transformStageOutputStageOutputなどです。 Pipelineは、transformメソッドのすべてに一般的にアクセスする必要があるPipelineStageのシーケンスのラッパーです。Scala - ポリモーフィズムのない多形抽象的特徴の実装

しかし、私は両方の解決策として根本的にうまくいきませんでした...最初は抽象的な多態性メソッドが非多態的な方法で実装されています(コンパイルされません)。 2番目はAbstractTraitが多形であるところのSeq[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] 
    } 

これはPipelineStage秒間問題を解決し、彼らは何の問題コンパイルを持っていない、と彼らの変換方法は、自分で細かい作業します。しかし、彼らは技術的にSeq[PipelineStage]は今無意味であるので、そのPipelineがコンパイルされません、今と同じ形質を実装していない...

は、多型なしで多型の抽象メソッドを実装する、またはシーケンスを参照のどちらかのために設立されたパターンがあります同じ抽象多型性を実装するクラス私の気持ちはノーで、おそらく私は間違った方法でこれに接近してきただろうが、恐らく私はどこかで行方不明になっている構文上のトリックがある。ありがとう。

+1

何らかの方法でコンパイルしたと仮定して、 'Pipeline'メソッドの本体を埋めて、' def stages:Seq [PipelineStage] 'にアクセスしてみてください。 その機能の使用方法を正確に表示します。 – Dima

答えて

4

最初のものは、あなたがすべてでやりたいしません:StageOutput1def transform[StageOutput1, StageOutput2](in: StageOutput1): StageOutput22はちょうどパラメータ名で、それは正確にdef transform[A, B](in: A): Bと同じ意味します。

私の提案は、第二を使用することですが、代わりにclass Pipelineのあなたは

def compose[C <: StageOutput](other: PipelineStage[B, C]): PipelineStage[A, C] = new PipelineStage[A, C] { 
    def transform(in: A) = other.transform(PipelineStage.this.transform(in)) 
} 

を追加し、必要なパイプラインを構築することができ、種類は実際に一致しました。

(は基本的には制約付きでFunction1ですが、他の方法を追加する予定がない場合や意図的に記述できる段階の種類を制限しない場合は、関数を使用して

+0

あなたは、最初のシナリオの 'PipelineStage1'の' transform'メソッドでポリモフィズムを削除するように編集しました。私がコンパイルしようとしたものではなく、タイプミスでした。 また、私はいくつかの他のメソッドと属性を 'PipelineStage'に持っていますので、私は特性を使う必要があります。 しかし、私は、実際には '' PipelineStage'と '' Pipeline''の間に根本的に異なるものはないと考えていませんでした。 'PipelineStage'に' Pipeline'に必要なすべてのメソッドを置き、あなたのcompose関数を使用することができます。ありがとう! –

+0

実際、 'PipelineStage'の代わりに' Pipeline'と呼ぶことをお勧めします。 –

関連する問題