考虑这个案例类
case class sample(val s: String = { /*compiled code*/ })
{
val name:String = { /*compiled code*/ }
val no:Int = { /*compiled code*/ }
}
我需要创建此类的实例,并将特定值设置为name和no。 但是我不能使用扩展这个类的另一个类。我必须传递相同的类实例。
答案 0 :(得分:2)
你的意思是有人遇到了确保name
和no
被设置为特定方式且无法更改的麻烦,并且你想让它们包含其他内容,这可能会违反所有种类假设?这不是一个好主意,JVM会阻止你做一些如此愚蠢的事情(除非涉及到所有内容的自定义类加载器的荒谬困难技巧)。
如果你只是想你想要设置那些val,但通常不必在构造函数中担心它们,那么有各种各样的解决方案。一种方法是使用lazy vals和私有变量来设置setter:
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")
}
以及上述的各种混合物也是可能的。
答案 1 :(得分: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