Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible and how to have var that can only be set once?

Tags:

scala

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]
}
like image 836
Anton Avatar asked Dec 21 '14 04:12

Anton


People also ask

How do you set a variable only once in C#?

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.

How do you initialize an object only once in Java?

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.


2 Answers

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.

like image 165
Chris Martin Avatar answered Oct 14 '22 15:10

Chris Martin


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
  }
like image 44
user5102379 Avatar answered Oct 14 '22 14:10

user5102379