-1

別のパターン マッチングのバグが発生しました。

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]) のきれいな (そしてよりメモリ効率の良い代替) として書かれました。

4

2 に答える 2

2

Scala-2.10.0-M6 では、コードは次のように出力します。

scala> 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)
pat@Float detected: Full(5.0,1.0)
pat@Float detected: Full(5.0,1.0)
full@Float detected: Full(5.0,1.0)

Full(5.0f, 1.0f)が一致Pattern(c: Float)するようになりました。他のテストは正常に機能しているようです。

于 2012-08-28T06:59:16.413 に答える
1

2.10.xまたはマスターでコードをテストしない限り、パターンマッチャーのバグを検索することは今のところほとんど役に立ちません。2つの理由:

  • パターンマッチャーには非常に多くのバグがあるため、適切なバグを見つけるのは非常に困難です。
  • 2.10.xのコードは完全に新しいため、古いパターンマッチャーのバグは、新しいパターンマッチャーには関係ありません(すべてではないにしても、ほとんどのバグが修正されました)。
于 2012-08-28T02:41:33.123 に答える