14

彼らはそれほどうまく混合していないようです:

abstract class A
case class B (var a: Int)(var b: String) extends A
case class C extends A

以下は機能しません。

B(1)("1") match {
  case B(a)(b) => print("B")
  case C() => print("C")
}

問題は、パターンマッチングとカレー引数が機能していないように見えることです。これに対する回避策はありますか?

4

3 に答える 3

12

クラスB用に作成されたunapply関数のシグネチャを見ると、次のようになっていることがわかりますunapply(x$0: Q): Option[Int]。したがって、unapply関数は、ケースクラスのパラメーターの最初の範囲で機能します。

これは、scala仕様(§5.3.2)によって確認されています。

ケースクラスの最初のパラメータセクションの正式なパラメータは要素と呼ばれます。それらは特別に扱われます。まず、このようなパラメーターの値は、コンストラクターパターンのフィールドとして抽出できます。

最初のパラメータセクションのみがエクストラクタを介して利用可能であると明確に主張しています。

いくつかの回避策:

  • パラメータをアンカリーします
  • 2つの値をテストする場合は、ガードとのパターンマッチングを使用します。case x@B(3) if x.b == "bazinga" => ...
  • 通常のクラスを使用し、独自の適用/適用解除を使用して独自のコンパニオンオブジェクトを定義します
于 2011-09-01T13:10:04.267 に答える
7

これの何が問題になっていますか?

def m(a: A) = a match {
  case b: B => print("B")
  case c: C => print("C")
}

あなたがこれ以上の機能を要求しなかったので、私はただ尋ねています。

編集

これは役立つ可能性があります:

object Dog {
   def apply(name: String)(size: Int) = new Dog(name)(size)
   def unapply(dog: Dog) = Some(dog.name, dog.size)
}
class Dog(val name: String)(var size: Int)

これで、次のような犬を作成できます。

new Dog("Snoopy")(10) 

またはこのように:

Dog("Snoopy")(10)

しかし、犬のパターンマッチでは、コンストラクターパターンはカレーされません

Dog("Snoopy")(10) match {
   case Dog(a, b) => // do sth with a or b
}
于 2011-09-01T12:53:07.077 に答える
2

通常のケースクラスを使用して、複数のパラメータリストを使用してファクトリメソッドを定義することができます。

于 2011-09-01T11:52:45.900 に答える