Scala 的不变性是否意味着列表不能被修改或者列表及其内容不能被修改?

A L*_*A L 0 oop functional-programming scala list immutability

我正在学习 Scala 和函数编程及其不变性概念。

如果我的代码对这样的对象列表进行操作:

class Devices(
  val devices_df: Dataset[Row],
){
  private lazy val _devices = _initialize_list_of_devices()

  def devices(): List[Device] = {
    _devices
  }

  private[this] def _initialize_list_of_devices(): List[Device] = {
    val devices_list = ListBuffer[Device]()
    for (device <- devices_df.collect()) {
      devices_list += new Device(
        device.getAs[String]("DeviceName"),
      )
    }
    devices_list.toList
  }
}
Run Code Online (Sandbox Code Playgroud)

我像这样初始化列表:

  val devices_list = new Devices(devices_df).devices()
Run Code Online (Sandbox Code Playgroud)

然后,我像这样更新列表中的对象:

  for (device <- devices_list) {
    device.modify_instance_properties()
  }
Run Code Online (Sandbox Code Playgroud)

该代码有效,我能够修改列表中的对象。

但是,当我尝试将另一个对象添加到列表中时,如下所示:

devices_list += new Device("append another device")
Run Code Online (Sandbox Code Playgroud)

无论是val devices_list或 ,它都会失败var devices_list

我只是想进行理智检查,确保我没有误解事情,并想确认这些都是真的:

  • 不变性并不意味着列表中的对象不能被修改
    • 这些对象似乎正在很好地更新它们的属性
  • 不变性确实意味着列表不能更改
    • 我应该无法将另一个对象添加到列表中或从列表中删除现有对象

感谢您的时间和帮助

Lui*_*rez 5

不可变集合也是如此List,这意味着它的内容不能更改。a 的实例List将始终包含相同的对象。

包含的对象List可以是或不是不可变的,如果这些对象可以修改其内容,那么您可以“修改List;但实际上List从未改变,因为它仍然指向相同的(可变的)对象。

Aval是一个不可变的引用,当您这样做时,val foo = x您是在说它将foo始终指向该x对象(同样,该对象可能是可变的或不可变的)

PS:您的所有代码都可以简化为:

final class Devices(val devices_df: Dataset[Row],) {
  lazy val devices =
    devices_df
      .collect()
      .iterator
      .map(device => device.getAs[String]("DeviceName"))
      .toList
}
Run Code Online (Sandbox Code Playgroud)

  • @ZhaoLi 是的,这正是我所说的,记住“List”要么是“Nil”,要么是“Cons(a: A, tail: List[A])”,所以基本上是一个包含对象和对象的单元格链指向下一个单元格,直到找到空单元格;因此在这种情况下,“List”是不可变的意味着您无法更改单元格,它们将始终是相同的单元格并指向相同的单元格。 (2认同)