別のパターン マッチングのバグが発生しました。
Googleはそれらをたくさん見つけます。そして、この Google リクエストは、scala でのメッセージベースのプログラミングの難しさについてユーザーに公平な情報を提供するために、akka のドキュメントで最初にリンクする必要があります。
このバグの一部は解決されていますが、一部は解決されていません。これらは一般的なものであり、1 つのバグに異なるコードが適用される場合があります。
2.9.2 で動作しなくなった部品が 1 つあります。バグの状態を知りたいです。そのため、コードに対応するバグを指摘してくれる scala バグ データベースに詳しい人の助けが必要です。
サンプルコード:
object Test {
sealed trait Pattern[T] {
val data : T
}
object Pattern {
def apply[T](data : T) : Pattern[T] = Primary(data)
def apply[T](data : T, f : Float) : Pattern[T] = Full(data,f)
def unapply[T](pat : Pattern[T]) : Option[T] = Some(pat.data)
}
final case class Primary[T](data : T) extends Pattern[T]
final case class Full[T](data : T, f: Float) extends Pattern[T]
val recognize1 : PartialFunction[Pattern[Any],Unit] = {
case pat@Pattern(d) => println("pattern recognized: " + pat)
case _ => println("simple failed")
}
val recognize2 : PartialFunction[Pattern[Any],Unit] = {
case pat@Full(x : Int, f) => println("full@Int detected: " + pat)
case pat@Pattern(c : Float) => println("pat@Float detected: " + pat)
case _ => println("full-pattern detection failed")
}
val recognize3 : PartialFunction[Pattern[Any],Unit] = {
case pat@Pattern(x : Int) => println("pat@Int detected: " + pat)
case pat@Pattern(c : Float) => println("pat@Float detected: " + pat)
case _ => println("pattern-pattern detection failed")
}
val recognize4 : PartialFunction[Pattern[Any],Unit] = {
case pat@Full(x : Int, f) => println("full@Int detected: " + pat)
case pat@Full(c : Float, f) => println("full@Float detected: " + pat)
case _ => println("full-full detection failed")
}
val allRecognize : List[PartialFunction[Pattern[Any],Unit]] =
List( recognize1, recognize2, recognize3, recognize4)
val tests : List[Any] = List(3) ++ List(5.0f)
def testAll() = for (t <- tests) {
println("test: " + t)
val primary = Pattern(t)
for (r <- allRecognize) r(primary)
val full = Pattern(t,1.0f)
for (r <- allRecognize) r(full)
println("")
}
}
および対応する出力:
scala> Test.testAll()
test: 3
pattern recognized: Primary(3)
full-pattern detection failed
pat@Int detected: Primary(3)
full-full detection failed
pattern recognized: Full(3,1.0)
full@Int detected: Full(3,1.0)
pat@Int detected: Full(3,1.0)
full@Int detected: Full(3,1.0)
test: 5.0
pattern recognized: Primary(5.0)
pat@Float detected: Primary(5.0)
pat@Float detected: Primary(5.0)
full-full detection failed
pattern recognized: Full(5.0,1.0)
full-pattern detection failed
pat@Float detected: Full(5.0,1.0)
full@Float detected: Full(5.0,1.0)
Int が最初に一致するため、Int のテストはうまく機能します。
Float を一致させると問題が発生します。Int と Float (パターンまたはフルのいずれか) に同じエクストラクタを使用すると、すべて正常に動作します。しかし、extractor を混ぜて Int を Full で抽出し、Float を Pattern で抽出しようとすると、すべてがうまくいきません。
主な質問: それはどのようなバグですか (それを理解するには scala の内部を知っておく必要があります)。
より少ない質問: これに対する最もエレガントな回避策は何ですか?
パターン特性は (U,Option[V]) のきれいな (そしてよりメモリ効率の良い代替) として書かれました。