Scala 编程示例混淆(清单 3.5,创建可变和不可变集)
Programming in Scala example confusion (Listing 3.5, creating mutable and immutable sets)
我对《Programming in Scala》第 3 版中清单 3.5 中的不可变集和可变集的理解有些困惑。该段落告诉我它正在创建不可变集,然后用 += 更新它,但是新存储的集包含所有三个元素。一些问题:
- 这与拥有可变集有何不同?不确定我是否看到了区别。
- 重新分配之前存在的旧集合会怎样?
- 如果您可以将一个新集合重新分配给
jetSet
变量,为什么还要费心称它为不可变集合?
- 是否有人在欺骗我并更改 PDF 中的“可变”和“不可变”? (别担心,我也买了实体书,很快就会到。)
摘自本书:
创建集合的默认方式如清单 3.5 所示:
var jetSet = Set("Boeing", "Airbus")
jetSet += "Lear"
println(jetSet.contains("Cessna"))
清单 3.5 - 创建、初始化和使用不可变集。
图 3.2 - Class Scala 集合的层次结构(不包括在内)。
在代码清单 3.5 的第一行代码中,您定义了一个名为 jetSet 的新变量,并使用包含两个字符串“Boeing”和“Airbus”的不可变集对其进行了初始化。如本示例所示,您可以在 Scala 中创建集合,方法与创建列表和数组的方式类似:通过在 Set 伴生对象上调用名为 apply 的工厂方法。在清单 3.5 中,您在 scala.collection.immutable.Set 的伴生对象上调用 apply,它 return 是一个默认的、不可变的 Set 的实例。 Scala 编译器将 jetSet 的类型推断为不可变的 Set[String].
要向集合中添加新元素,您可以在集合上调用 + 并传入新元素。在可变集和不可变集上,+ 方法将创建并 return 一个添加了元素的新集。在清单 3.5 中,您使用的是一个不可变集。尽管可变集提供了实际的 += 方法,但不可变集却没有。
在这种情况下,第二行代码“jetSet += "Lear"”本质上是 shorthand 用于:
jetSet = jetSet + "Lear"
因此,在清单 3.5 的第二行中,您使用新的集合重新分配了 jetSet 变量
包含“Boeing”、“Airbus”和“Lear”。最后,清单 3.5 的最后一行打印出该集合是否包含字符串“Cessna”。 (如您所料,它打印出错误。)
如果你想要一个可变集,你需要使用导入,如清单 3.6 所示:
import scala.collection.mutable
val movieSet = mutable.Set("Hitch", "Poltergeist")
movieSet += "Shrek"
println(movieSet)
提前致谢!
jetSet
是一个 var
。它在 +=
赋值之后引用了一个新的和不同的 Set
。
What happens to the old set that is existed before reassignment?
如果前面的 2 元素 Set
没有被任何其他变量引用,那么它将被垃圾收集掉。
movieSet
是一个 val
。它总是引用相同的 Set
,即使 Set
改变了它的值。
突变通常被认为是不可取的,有经验的 Scala 编码人员会避免这两种情况。
我对《Programming in Scala》第 3 版中清单 3.5 中的不可变集和可变集的理解有些困惑。该段落告诉我它正在创建不可变集,然后用 += 更新它,但是新存储的集包含所有三个元素。一些问题:
- 这与拥有可变集有何不同?不确定我是否看到了区别。
- 重新分配之前存在的旧集合会怎样?
- 如果您可以将一个新集合重新分配给
jetSet
变量,为什么还要费心称它为不可变集合? - 是否有人在欺骗我并更改 PDF 中的“可变”和“不可变”? (别担心,我也买了实体书,很快就会到。)
摘自本书:
创建集合的默认方式如清单 3.5 所示:
var jetSet = Set("Boeing", "Airbus")
jetSet += "Lear"
println(jetSet.contains("Cessna"))
清单 3.5 - 创建、初始化和使用不可变集。 图 3.2 - Class Scala 集合的层次结构(不包括在内)。 在代码清单 3.5 的第一行代码中,您定义了一个名为 jetSet 的新变量,并使用包含两个字符串“Boeing”和“Airbus”的不可变集对其进行了初始化。如本示例所示,您可以在 Scala 中创建集合,方法与创建列表和数组的方式类似:通过在 Set 伴生对象上调用名为 apply 的工厂方法。在清单 3.5 中,您在 scala.collection.immutable.Set 的伴生对象上调用 apply,它 return 是一个默认的、不可变的 Set 的实例。 Scala 编译器将 jetSet 的类型推断为不可变的 Set[String].
要向集合中添加新元素,您可以在集合上调用 + 并传入新元素。在可变集和不可变集上,+ 方法将创建并 return 一个添加了元素的新集。在清单 3.5 中,您使用的是一个不可变集。尽管可变集提供了实际的 += 方法,但不可变集却没有。
在这种情况下,第二行代码“jetSet += "Lear"”本质上是 shorthand 用于:
jetSet = jetSet + "Lear"
因此,在清单 3.5 的第二行中,您使用新的集合重新分配了 jetSet 变量 包含“Boeing”、“Airbus”和“Lear”。最后,清单 3.5 的最后一行打印出该集合是否包含字符串“Cessna”。 (如您所料,它打印出错误。)
如果你想要一个可变集,你需要使用导入,如清单 3.6 所示:
import scala.collection.mutable
val movieSet = mutable.Set("Hitch", "Poltergeist")
movieSet += "Shrek"
println(movieSet)
提前致谢!
jetSet
是一个 var
。它在 +=
赋值之后引用了一个新的和不同的 Set
。
What happens to the old set that is existed before reassignment?
如果前面的 2 元素 Set
没有被任何其他变量引用,那么它将被垃圾收集掉。
movieSet
是一个 val
。它总是引用相同的 Set
,即使 Set
改变了它的值。
突变通常被认为是不可取的,有经验的 Scala 编码人员会避免这两种情况。