5

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

case class sample(val s: String = { /*compiled code*/ })
{
  val name:String = { /*compiled code*/ }
  val no:Int = { /*compiled code*/ }
}

特定の値を name と no に設定して、このクラスのインスタンスを作成する必要があります。しかし、このクラスを拡張する別のクラスを使用することはできません。同じクラス インスタンスを渡す必要があります。

4

2 に答える 2

2

誰かが面倒を見て特定の方法に設定されてnameおりno、変更できないことを意味し、あらゆる種類の仮定に違反する可能性のある何か他のものをそれらに含めたいと考えていますか? それは良い考えではありません.JVMは、あなたがそんなにばかげたことをするのを止めます.

これらの値を設定したいだけで、通常はコンストラクターでそれらを気にする必要がないという意味であれば、さまざまな解決策があります。1 つは、セッターで lazy val と private var を使用することです。

case class C(val s: String = "fish") {
  private var myN: Option[Int] = None
  def initializeN(n0: Int) {
    myN = Some(n0)
    if (n != n0) throw new Exception("Already initialized")
  }
  lazy val n: Int = myN.getOrElse(s.length)   // s.length is your code block
}

次のように機能します。

scala> C("salmon")
res0: C = C(salmon)

scala> res0.initializeN(2); res0.n
res1: Int = 2

scala> C("herring")
res1: C = C(herring)

scala> res1.n
res2: Int = 5

scala> res1.initializeN(2)
java.lang.Exception: Already initialized
    at C.initializeN(<console>:11)
        ...

初期化のコンパイル時の安全性が必要な場合は、他にもさまざまなトリックを実行できます。後のパラメーター ブロックは前のものを参照でき、一致する引数として表示されません。

case class D(val s: String = "fish")(val n: Int = s.length) {}

コンストラクターをオーバーロードできます。

case class E(val s: String, n: Int) {
  def this(s: String) = this(s, s.length)
  def this() = this("fish")
}

また、上記のさまざまな混合物も可能です。

于 2013-03-06T13:30:08.490 に答える
1

そして、作成nameおよびnoコンストラクターパラメーターはオプションではありませんか?

case class Sample(s: String = { /*compiled code*/ },
                  name: String = { /*compiled code*/ },
                  no: Int = { /*compiled code*/ })

/* compiled code */がフィールドのデフォルト値を決定すると仮定します。次のようにコードを使用できます。

Sample()                   // all default values
Sample("some value for s") // default values for name and no
Sample("s", "name", 123)   // explicit values, no defaults
于 2013-03-06T13:17:52.473 に答える