Consider this case class
case class sample(val s: String = { /*compiled code*/ })
{
val name:String = { /*compiled code*/ }
val no:Int = { /*compiled code*/ }
}
I need to create instance of this class with particular values set to name and no. But I cannot use another class which extends this class. I have to pass the same class instance.
You mean someone has gone to the trouble of making sure name
and no
are set a particular way and cannot be changed, and you want to make them contain something else, which may violate all sorts of assumptions? That's not a good idea, and the JVM will stop you from doing something so foolish (barring absurdly difficult tricks involving custom classloaders for everything).
If you merely mean that you want to set those vals, but not usually have to worry about them in the constructor, then there are a variety of solutions. One is to use lazy vals and private vars with setters:
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
}
Which works like so:
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)
...
There are various other tricks you can play if you want compile-time safety of initialization. Later parameter blocks can refer to earlier ones, and don't appear as match arguments:
case class D(val s: String = "fish")(val n: Int = s.length) {}
You can overload constructors:
case class E(val s: String, n: Int) {
def this(s: String) = this(s, s.length)
def this() = this("fish")
}
and various mixtures of the above are possible also.
And making name
and no
constructor parameter is not an option?
case class Sample(s: String = { /*compiled code*/ },
name: String = { /*compiled code*/ },
no: Int = { /*compiled code*/ })
I assume that the /* compiled code */
determines the default values of the fields. You can use the code as follows:
Sample() // all default values
Sample("some value for s") // default values for name and no
Sample("s", "name", 123) // explicit values, no defaults
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With