2016-06-27 9 views
1

次の例では、bar1はコンパイルされますが、bar2はどのようにコンパイルされているのか理解できません。戻り値の型に一致する型の汎用値に対してパターンマッチを実行する

trait Key[T] { 
} 

trait KeyString extends Key[String] 

class Foo { 
    def bar1[T](key: Key[T]): T = key match { 
     case k: KeyString => "hallo" 
     } 

    /*def bar2[T](key: T): T = key match { 
      case k: String => "hallo" 
      }*/ 
} 

コードサンプルのオンライン:http://www.tutorialspoint.com/compile_scala_online.php?PID=0Bw_CjBb95KQMZGtUOU9yYXpWcEE

誰かが説明してもらえ、なぜBAR1にコンパイラが「ハロー」は型TのとことはできませんBAR2であることを、把握することができます。 私はかなりの時間を捜し、説明を思いつくことができませんでした。

ありがとうございます。

答えて

0

bar2の状況は、最初に表示されるより複雑です。例えば。 StringというサブクラスがString1と呼ばれていたとします。そして、TString1の場合、keycase k: Stringと一致しますが、"hallo"のタイプが間違っています。そのようなサブタイプはありません。Stringが最終的に起こるためですが、これがコンパイルされているかどうかは、最終結果によってはStringに依存する場合もあります。この特定のパターン(GADT:generalized algebraic data typeと呼ばれる)が特別なコンパイラサポートを持っているため、

bar1が働きます。このサポートは完全ではありません。 https://gist.github.com/pchiusano/1369239

+0

あなたの優れた答えに感謝します。私が理解していないただ一つの事柄:Stringの最終性(または一般的に結果の型)に基づいてコンパイルされたのはなぜ奇妙なのでしょうか?結果の型がfinalで、一致した型と等しい場合は、Tがその型と等しいことを推測するのは正しいでしょう。 – Cornelius

+1

私は自分自身で答えを見つけました.Tは依然としてインスタンスのシングルトンタイプであり、最終性は排除しません。 参照:https://issues.scala-lang.org/browse/SI-127 – Cornelius

関連する問題