2012-09-09 22 views
5

誰かが次のコードをコンパイルする理由を説明できますか?スカラパターンマッチングと型推論

Option("foo") match { 
    case x: List[String] => println("A") 
    case _ => println("B") 
} 

これは、タイプの消去に関する警告が表示されますが、まだコンパイルされます。私はの代わりに"foo"にマッチした場合と同じように、これが型エラーを投げることを期待していました。

ありがとうございます!

+1

バグのようです。私はそれを報告するだろう。 – sschaef

答えて

2

私は、コンパイラがOptionListの両方をProductとして扱っていると仮定します。そのため、コンパイルが行われます。あなたが言うように、タイプ消去に関する警告が期待されます。ここでは他の製品を使用する例です。(理由は以下のコメントの)R/Tケースクラス/ W

scala> Option("foo") match { 
| case x: Tuple2[String,String] => println("TUPLE") 
| case x: List[String] => println("LIST") 
| case _ => println("OTHER") 
| } 
<console>:9: warning: non variable type-argument String in type pattern (String, String)  is unchecked since it is eliminated by erasure 
      case x: Tuple2[String,String] => println("TUPLE") 
       ^
<console>:10: warning: non variable type-argument String in type pattern List[String] is unchecked since it is eliminated by erasure 
      case x: List[String] => println("LIST") 
       ^

UPDATE:

scala> case class Foo(bar: Int) 
defined class Foo 

scala> val y: Product = Foo(123) 
y: Product = Foo(123) 
+0

'Product'とは関係ないようです。私は 'option(" foo ")を単一のパラメータを取る自分のケースクラスに置き換えました。エラーはありません。 – ghik

+2

Errr、ケースクラスによって自動的にProductが拡張されます。レスポンスの編集を参照してください。 – timothy

+1

まあまあですが、実際にはケースクラスである必要はありません。通常の非最終クラスでもエラーは発生しません。 – ghik

0

私はエラーがときのクラスに示されていることに気づきました一致する値はfinalと宣言されています(最終的にはStringとなります)。私はまだそれがなければエラーがない理由はまだ分からない。

4

コードをコメントし、その者はそれを味わうために時間を割いてみましょうさ:なしは、例えば、最終ではないと

/** If we can absolutely rule out a match we can fail early. 
    * This is the case if the scrutinee has no unresolved type arguments 
    * and is a "final type", meaning final + invariant in all type parameters. 
    */ 

注意してください。私は当然知っている?

あなたは-Ypatmat-デバッグscalacをしようとすると、ここでコメントは役立つかもしれない:

https://github.com/scala/scala/pull/650

到達可能性はほとんど手の届くところにある。

https://issues.scala-lang.org/browse/SI-6146

しかし、私は表示されませんいつか警告できるものについての約束。パフォーマンス上の理由から?また、[Foo [_]]というインスタンスについて警告する必要があるのはなぜですか?

今のところ、仕様セクション8.2 - 8.4はFoo [a]とのマッチングが興味深い理由(なぜなら、aが取得するため)を奨励しています。私は再びそれを読むつもりだと思う。コーヒーを飲んだ後。

trait Foo[+A] 
final class Fuzz[+A] extends Foo[A] 
final object Fooz extends Foo[Nothing] 
object Futz extends Foo[Nothing] 

//error 
Fooz match { 
    case x: List[_] => println("A") 
    case _ => println("B") 
} 
//no error 
Futz match { ... } 
+0

ニースは、パターンマッチャーでいくつか変わったかもしれないが、昨晩遅くそれを見ることができないと考えました:-) – timothy