Is there a native way to make sure that a variable can only be set once?
Currently, I am using this approach
class SetOnceVariable[T]
{
private var value : T = _
private var initialized = false
def apply(_v : T = _) : T =
{
if (value != null && !initialized) {
value = _v
initialized = true
}
value
}
}
class ClientInfo
{
val userIP : SetOnceVariable[String] = new SetOnceVariable[String]
}
To do this, first you have to make a bool variable that tells you if the variable has been set: bool isSet; Then, we make the variable be true when the variable you want to be able to be set only once is set. Note that this returns null if this variable is accessed before it is set.
Since you want a single value per instance, you can use an instance member variable, outside the method. You can do that with instance members too - just use a different instance member for each method that in C you'd use a static local variable.
There's no such language construct, but I think I can clean up your code, at least.
class SetOnce[A](var toOption: Option[A] = None) {
def set(a: A): Unit = if (toOption.isEmpty) toOption = Some(a)
def get: A = toOption.get
}
Usage:
val x = new SetOnce[Int]
x.toOption // None
x.set(1)
x.get // 1
x.set(2)
x.get // 1
I omitted the null
consideration because idiomatic Scala code tends to not use or consider null
outside of Java compatibility. We mostly pretend that it doesn't exist.
Approach using lazy:
class SetOnceVariable[T] {
private var v: T = _
private lazy val value: T = v
def apply(_v: T = ???): T = {
v = _v
value
}
}
val info = new ClientInfo
println(info.userIP("IP")) // IP
println(info.userIP("IP2")) // IP
println(info.userIP("IP3")) // IP
To make it threadsafe you can use:
def apply(_v: T = ???): T =
synchronized {
v = _v
value
}
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