考虑这个案例类
case class sample(val s: String = { /*compiled code*/ })
{
val name:String = { /*compiled code*/ }
val no:Int = { /*compiled code*/ }
}
我需要创建此类的实例,并将特定值设置为 name 和 no。但是我不能使用扩展这个类的另一个类。我必须传递相同的类实例。
考虑这个案例类
case class sample(val s: String = { /*compiled code*/ })
{
val name:String = { /*compiled code*/ }
val no:Int = { /*compiled code*/ }
}
我需要创建此类的实例,并将特定值设置为 name 和 no。但是我不能使用扩展这个类的另一个类。我必须传递相同的类实例。
你的意思是有人费力地确定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")
}
并且上述的各种混合物也是可能的。
并且制作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