21

このクラスを検討してください。

class DateTime(year: Int, month: Int, day: Int)(hour: Int, minute: Int, second: Int)

unapply次のようなものと照合したい場合、メソッドはどのようになりますか?

dt match {
  case DateTime(2012, 12, 12)(12, _, _) => // December 12th 2012, 12 o'clock
  /* ... */
}

私はこれを試しました:

def unapply(dt: DateTime) = 
  Some((dt.year, dt.month, dt.day),(dt.hour, dt.minute, dt.second))

しかし、それは実際には機能しませんでした。

4

3 に答える 3

24

ケースクラスは、最初のパラメーターセットでのみ一致します(そして他の気の利いたことを行います)。

scala> case class A(i: Int)(j: Int) { }
defined class A

scala> A(5)(4) match { case A(5) => "Hi" }
res14: java.lang.String = Hi

scala> A(5)(4) == A(5)(9)
res15: Boolean = true

ケースクラスでない場合は、una​​pplyを任意に定義できるため、実際にはクラスの実装者次第です。デフォルトでは、適用解除はありません。そのため、タイプでのみ一致させることができます。

すべてを一致させて平等にすることができるなど、気の利いたケースクラス機能を使用したいが、ある種の分割がある場合は、ケースクラスをネストできます。

case class Time(hour: Int, minute: Int, second: Int) { }
case class Date(year: Int, month: Int, day: Int) { }
case class DateTime(date: Date, time: Time) { }

scala> val dt = DateTime(Date(2011,5,27), Time(15,21,50))
scala> dt match { case DateTime(Date(2011,_,_),Time(h,m,50)) => println(h + ":" + m) }
15:21
于 2011-05-27T19:18:20.017 に答える
10

Rexの答えに基づいて構築するために、最初のパラメーターブロックでパターンマッチングのみを行うことができるだけでなく、この動作は設計によるものです。

さらに興味深い質問は、代数的データ型としてのケースクラスが複数のパラメータリストをサポートする理由です...

ケースクラスに特別な動作を追加するのに十分な正当性はなく、複数のパラメータリストが非常に便利であることがわかります。本番コードでは、この機能は暗黙の引数を提供するためにのみ使用されることが多く、当然のことながらパターンマッチングは必要ありません。

于 2011-05-27T23:04:16.063 に答える
1

Some((a,b),(x,y))Scalaにはコンマ演算子がなく、エクストラクタから戻ってきたため、おそらく機能しませんでした。代わりに使用した場合Some(((a,b,c),(x,y,z)))(つまり、Tuple2[Tuple3[A,B,C],Tuple3[X,Y,Z]]おそらく機能すると思います。

于 2011-05-27T22:36:24.460 に答える