2017-09-29 13 views
1

でオーバーライドされたメンバ変数のタイプを考え出す私はこのようなタイプの階層構造を持っている:Scalaの

trait Description { 

} 

trait DescriptionProvider { 
    val description: Description 
} 

object Sample extends DescriptionProvider { 
    object description extends Description { 
    val name = "foo" 
    } 
} 

は今、私は私にDescriptionProviderのいずれかのサブタイプのための具体的な値a.descriptionを与える関数f、探しています、それを含むタイプです。

など。 f(Sample).nameはコンパイルしてfooと評価する必要があります。

明白なアクセス方法はもちろん

def obvious[T <: DescriptionProvider](x: T) = x.description obvious(Sample).name // doesn't compile of course, as foo returns only Description.

を動作することはできません(すでに存在し、巨大である)オブジェクト階層の大幅な変更を行うことなく、このような関数fを設計する方法を任意のトリックはあります?

私は既に何らかの方法で動作するマクロを使用しようとしましたが、IntelliJはそれを好まない(上記の例では.nameが赤で表示されます)。

私はScala 2.10を使用していますが、今は変更できません。

答えて

1

が代わりに推論に頼るのパス依存のいずれかで、あなたの戻り値の型注釈:

def obvious[T <: DescriptionProvider](x: T): x.description.type = x.description 

を私は2.10.6でScastie snippetを作り、それが動作しているようです。しかし、Intellijが苦情を申し立てないかどうかは確認できません。

+0

ありがとう、これは動作します! (IntelliJもそれを受け入れます) – nob

0

は、なぜあなたは、あなたのDescription形質にnameを追加しないでください:

trait Description { 
    val name: String 
} 

trait DescriptionProvider { 
    val description: Description 
} 

object Sample extends DescriptionProvider { 
    object description extends Description { 
    override val name: String = "foo" 
    } 
} 

object Main extends App{ 

    def obvious[T <: DescriptionProvider](x: T) = x.description 

    val description: String = obvious(Sample).name 

    println(s"description = ${description}") 

} 

今、あなたは、コードをコンパイルして実行することができます。 nameDescriptionの特性に追加すると、コンパイラはDescriptionnameがあることを認識します。

+0

いいえ、これは私の場合は機能しません。私の場合、 'DescriptionProvider'の各サブクラスは' Description'に異なるメンバーを追加しています。 – nob

+0

次に 'Description'を拡張して' name'フィールドをその特性の下に置く 'NameDescription'特性を作成してみてください。次に 'NameDescription'にパターンマッチングを介して' apparent'メソッドのレスポンスをキャストすることができます。そうすることで、 '.name'を呼び出すことができます。 – fcat

+0

Mm ..ほとんどの 'Description'フィールドは全く異なっています。これは、各タイプのDB列を記述するDSLで使用されます。私は、何らかの種類のMagic型クラスパラメータによってメンバ型にアクセスする関数fをもっと考えました。しかし、私はこのパラメータのインスタンスを作成するために、(Macrosを除いて)方法を見つけませんでした。 – nob