Scala 是否有 "Scala Way" 来使用或设置变量?

Does Scala have a "Scala Way" to use or set a variable?

如果设置了实例变量,我想使用它。如果未设置,则执行设置工作。

这就是我想要的并且有效:

class Devices(){
  private var _devices = List[Any]()

  def devices(): List[Any] = {
    // possibly other stuff
    _get_devices() // return processed list of devices
  }

  private[this] def _get_devices(): List[Any] = {
    if (_devices.isEmpty) {
      _devices = _initialize_list_of_devices()
    }
    _devices
  }

  private[this] def _initialize_list_of_devices(): List[Any] = {
    List[String]("_initialized") // perform time-consuming processing
  }
}

但我想知道是否有更惯用的 Scala 方法。

我也无法使用lazy val,因为我需要稍后修改变量。

在 Ruby 中,它会像延迟加载、记忆或这样:

def my_attribute
  @my_attribute ||= initialize_my_attribute
end

def my_attribute
  @my_attribute = (value || initialize_my_attribute)
end

感谢您的宝贵时间

您可以使用 lazy val 将变量的初始化推迟到第一次访问时:

class Devices(){
  private lazy val _devices: List[Any] = {
    List[String]("_initialized") // perform time-consuming processing
  }
}

从多个线程访问 lazy vals 是安全的。

我只是想把它打出来,这样我以后就不会忘记它,以防以后对别人有帮助。

@kolmar 的回答和@SwiftMango 的评论让我想到了这个:

Devices.scala:

class Devices(){
  println("in constructor")
  lazy val _devices = _initialize_list_of_devices() // I swapped these two statements
  //val _devices = _initialize_list_of_devices()    // to get at the results below

  def devices(): List[Any] = {
    println("in getter")
    _devices
  }

  private[this] def _initialize_list_of_devices(): List[Any] = {
    println("initializing=======")
    List[String]("_initialized") // perform time-consuming processing
  }
}

Main.scala:

  var devices_class = new Devices()
  val devices_list = devices_class.devices()
  devices_class.devices()

输出是这样的:
没有 lazy(即 val _devices = _initialize_list_of_devices():

in constructor
initializing=======
in getter
in getter

lazy(即 lazy val _devices = _initialize_list_of_devices():

in constructor
in getter
initializing=======
in getter

我学到并弄清楚的是:

  • lazy 不会多次保持 运行ning 的初始化过程,即它不会执行 caching/memoizing
  • lazy 确实将初始化推迟到使用变量时,即它正在做 lazy-loading/evaluating
  • val 帮助程序员记住不要重新分配给变量(与 var 相反);因此,(以一种迂回的方式)有助于将初始化过程保持为 运行 一次,即帮助程序员记住使用变量的 cached/memoized 值。

我在懒惰和 memoize/caching 之间感到困惑。

再次感谢大家的帮助