1

コンストラクタの引数を交換することは可能ですか? 次の例を検討してください。

case class Foo(a:Int, b:Int) {
  if (a > b) {
    val tmp = a
    a = b
    b = tmp
  }
}

4 行目でval を再割り当てするため、コンパイラはエラーをスローしますが、aこれはまったく問題ありません。ただし、不変オブジェクトが必要です。aしたがって、 andbを変数として宣言することはできません。

この問題を解決する既知のパターンはありますか?

4

4 に答える 4

4

内部スワップ メソッドを作成します。

case class Foo(a: Int, b: Int) {
  def ifSwap = if (a > b) Foo(b, a) else this
}

val f1 = Foo(1,2).ifSwap // the result is Foo(1,2)
val f2 = Foo(2,1).ifSwap // the result is Foo(1,2)

不変性を維持したい場合、状態を変更するには、変更ごとに新しいインスタンスを返すか、LensesStateRecordsなどのハードコアな方法を使用する必要があります...そして、オデルスキー教授がSD'13トークで語ったように、恐れてはいけない状況vars

于 2013-07-17T11:23:53.410 に答える
3

Fooのすべてのインスタンスが値のペアを順序付けることを達成したいと思いますか?

1 つの可能性は、クラスを作成せずに、caseその構築と抽出を自分で定義することです。クラスは製品から継承されず、きれいなデフォルトtoStringなどもありませんが、それ以外の場合はケース クラスとして使用できます。

class Foo private (val a: Int, val b: Int);
object Foo {
  def apply(a: Int, b: Int): Foo =
    if (a < b)
      new Foo(a, b)
    else
      new Foo(b, a)

    def unapply(f: Foo): Option[(Int,Int)] = Some((f.a, f.b))
}

// test:
def printFoo(f: Foo) = f match {
  case Foo(x, y) => println(x + ", " + y);
}
printFoo(Foo(1,2))
printFoo(Foo(3,2))

以下も参照してください。

于 2013-07-17T13:18:51.597 に答える