2016-03-23 8 views
0

Scalaコンパイラ(バージョン2.11.7)がオブジェクト(別名型メンバー)で定義された型に関する型情報をどのように渡すのか疑問に思っています。入れ子型の型情報を保持する

(new Bar).myCall 

それが正常に動作し、私は20が返された値を取得する:私はこのようなコールを持っている場合、

trait Foo { 
    type Contents <: Any 
    val value: Contents 
    // Just a mock function call that uses a manifest. 
    def myCall(implicit mf: Manifest[Contents]): Contents = value 
} 

class Bar extends Foo { 
    type Contents = Int 
    val value = 20 
} 

class Baz extends Foo { 
    type Contents = String 
    val value = "it's baz" 
} 

は、これらのクラスを考えてみましょう。同様に、このような呼び出しを行うことも動作します。この場合

List(new Bar, new Bar).head.myCall 

を、私はまだ20が返されます。私はFooのリストからコールを行う場合は、このような何か:

List(new Bar, new Baz).head.myCall 

は、私は、コールのために利用可能なマニフェストがないと言って、コンパイラのエラーを得ました。私の質問は、Manifest(またはTypeTag〜実際には関係ない)をどこかに渡すことが可能かどうかです。もしそうなら、どうですか?それはBarBaz最安の一般的なタイプですので、あなたの第2のケースで

答えて

1

は、あなたのListの根本的なタイプはFooです。これは、頭部がタイプFooであることを意味します。パターンマッチで正確なタイプを見つけることができます:

val maybeBar = List(new Bar, new Baz).head 
maybeBar match { 
    case b: Bar => println(b.myCall) // 20 
    case b: Baz => println(b.myCall) // it's baz 
    case _ => println("?") 
} 
+0

ありがとうございます。しかしこれには事前に「バー」と「バズ」を知っておく必要があります。 'Foo'がどのように拡張されるのか分からなければ、動作させる方法はありますか? – bow

+0

あなたが知っているように、「Fooを拡張しているT」のマッチングはうまくいきません。構造型(別名:ダックタイピングとも呼ばれます)と呼ばれる別の可能性があります。これは、「パターンに一致するメソッドmyCallを持つ型」です。しかし、私はあなたがそのように適切なマニフェストを注入できるとは思わないが、私は間違っているかもしれない(構造型は私が多くの経験を持っていないタイプのアクロバットである)。 http://stackoverflow.com/questions/1988181/pattern-matching-structural-types-in-scalaを参照してください。 – slouc

関連する問題