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 会阻止你做如此愚蠢的事情(除非涉及到所有事情的自定义类加载器的荒谬困难的技巧)。

如果您只是想设置这些 val,但通常不必在构造函数中担心它们,那么有多种解决方案。一种是使用带有 setter 的惰性 val 和私有 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

并且制作nameno构造函数参数不是一个选项?

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 回答