次のコードがコンパイルされる理由を誰か説明できますか?
Option("foo") match {
case x: List[String] => println("A")
case _ => println("B")
}
これにより、型の消去に関する(予期される)警告が表示されますが、それでもコンパイルされます。"foo"
の代わりにon にマッチした場合のように、これは型エラーをスローすると予想していましたOption("foo")
。
ありがとう!
次のコードがコンパイルされる理由を誰か説明できますか?
Option("foo") match {
case x: List[String] => println("A")
case _ => println("B")
}
これにより、型の消去に関する(予期される)警告が表示されますが、それでもコンパイルされます。"foo"
の代わりにon にマッチした場合のように、これは型エラーをスローすると予想していましたOption("foo")
。
ありがとう!
コードにはコメントが付けられています。
/** 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.
*/
たとえば、 None は最終的なものではないことに注意してください。私は当然知っている?
scalac -Ypatmat-debug を試したことがあれば、ここのコメントが役立つかもしれません:
https://github.com/scala/scala/pull/650
到達可能性はほぼ手の届くところにあります:
https://issues.scala-lang.org/browse/SI-6146
しかし、いつの日か警告できる可能性があるという約束は見当たりません。パフォーマンス上の理由で?また、なぜ instanceOf[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 { ... }
コンパイラは と の両方Option
をList
として扱っていると思いProduct
ます。これがコンパイルする理由です。あなたが言うように、型消去に関する警告が予想されます。別の製品を使用する例を次に示します。
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 w/r/t ケース クラス (以下のコメントのため):
scala> case class Foo(bar: Int)
defined class Foo
scala> val y: Product = Foo(123)
y: Product = Foo(123)
一致する値のクラスが final として宣言されている場合にエラーが表示されることに気付きました (それが final であることはわかっていString
ます)。それがないとエラーが発生しない理由はまだわかりません。