2

この例を見つけたとき、私はパターンマッチングを学ぼうとしていました。ケースクラスのパターンマッチングは、オーバーロードされたケースクラスのコンストラクターでは機能していないようです。

case class MyClass(var first:String, var last:String){
 def this(first: String) = this(first, "")
 override def toString = "First: "+ first + " Last:" +last
}

val myClassTwo = new MyClass("a", "b")
myClassTwo match {
   case MyClass(a,b) => println("two constructor matched")
   case MyClass(a) => println("one constructor matched")
   case _ => println("Not matched")
  } 

「caseMyClass(a)」行で「パターンMyClass(first:String、last:String)の引数の数が間違っています。」というコンパイルエラーが発生します。オーバーロードされたコンストラクターでパターンマッチングが機能することを期待していましたが、機能していません。誰かがこの振る舞いを説明してもらえますか?

また、1つのコンストラクターパラメーターで間違った結果が得られます。

 val myClassOne = new MyClass("a")      
  myClassOne match {
   case MyClass(a,b) => println("two constructor matched")
   case _ => println("Not matched")
  } 

myClassOneこれにより、アグリメントが1つしかない場合でも、「2つのコンストラクターが一致」します。説明してください。

4

2 に答える 2

17

何が起こっているのかを理解するには、ケース クラスでのパターン マッチングが というメソッドの構文であることを知っておく必要がありますunapply。これについては、A Tour of Scala: Extractor Objects で説明されています。

REPL を使用すると、メイン コンストラクターのパラメーターに対応するunapplyのコンパニオン オブジェクトで、コンパイラーがメソッドを生成したことがわかります。MyClass

scala> MyClass.unapply _
res0: MyClass => Option[(String, String)] = <function1>

ただし、コンパイラは、( を使用して) 定義した補助コンストラクターのエクストラクターを生成しませんthis()。追加を自分で定義しようとすると、そのunapply理由がわかります。まったく同じパラメーター ( のインスタンスMyClass) を持つ別のメソッドでメソッドをオーバーロードすることはできません。

補助コンストラクターを使用してインスタンスを作成するとnew MyClass("a")、それは完全に構築されたインスタンスであるMyClassため、生成されたunapplyメソッドは引き続き有効です。のパターンは、およびにcase MyClass(a,b)一致aします。"a"b""

于 2013-03-04T10:09:29.830 に答える
3

ベンの答えは完璧です..

気にしないパラメーターにcase class使用することで、一致する方法を見つけることができます..._

myClassOne match {
   case MyClass("a","b") => println("two constructor matched")
   case MyClass("a",_) => println("one constructor matched")
   case _ => println("Not matched")
  } 
于 2013-03-04T12:51:44.187 に答える