【问题标题】:What is better: var with mutable.ListMap or var with immutable.ListMap?哪个更好:var 与 mutable.ListMap 或 var 与 immutable.ListMap?
【发布时间】:2019-08-19 14:43:38
【问题描述】:

我有一个var 变量与immutable.ListMap 类型的简单用法。不幸的是,项目的代码复杂性并没有给我机会将其移至immutable val

在审查时,我收到一条评论,将其更改为 var 变量和 mutable.ListMap。 就像“你已经拥有 var 并且 mutable 不会让事情变得更糟。”

你怎么看?是否有任何性能指标或代码风格禁止使用可变变量?在mutable varimmutable var 之间选择哪个更好?

我已经阅读了所有的答案

val-mutable versus var-immutable in Scala 并注意到一条获得很多赞的评论:

更喜欢不可变的 val 而不是不可变的 var,而不是可变的 val,而不是可变的 var

该陈述是否有任何证据或解释?

【问题讨论】:

  • 你为什么要把它改成mutable var?我的意思是,您是否需要更改对象 (var) 的引用或改变对象本身 (mutable)?如果你真的需要两者,我建议仔细审查代码的设计。为什么?因为你暴露的突变越多,就越容易破坏,更难推理代码。如果您出于任何原因确实需要可变性,那么请将其保持在尽可能小的范围内。
  • 不,我不需要两者,我只是想在审查时考虑一个好的答案,即双重可变性是一个坏主意。

标签: scala immutability var


【解决方案1】:

var 具有可变集合是双重可变性。

var mm : scala.collection.mutable.xxx = ???

这意味着 mm 持有的集合可以并且可能会随着时间而改变和/或 mm 本身可以更改以引用完全不同的集合。

可变集合有时很有用。很少需要可变变量,应避免使用。可变集合类型的可变变量?我只是不明白这有什么理由。

【讨论】:

    【解决方案2】:

    ListMap 实际上是一个很好的例子,因为在多线程环境中,即使您只是查看,您也必须synchronize。 另一方面,var 分配是原子的,您根本不需要 synchronize,只需将其标记为 @volatile

    这是性能优势和可靠性(当您的东西需要synchronized 访问时,有人忘记正确编码只是时间问题)。

    所以,是的,如果您由于某种原因不能使用“不可变 val”,那么绝对更喜欢“不可变 var”而不是“可变 val”,除非有明确而具体的理由要求您的容器是可变的(例如,地图真的很大,而且经常更新,导致可衡量的性能问题)。

    至于“可变变量”,是的,就像提到的其他答案一样,我也不知道为什么你想要拥有 那个

    【讨论】:

    • 使用 volatile 使分配原子化(以显着的性能成本为代价),但您可能仍需要同步对数据结构的访问,甚至是不可变的数据结构。
    • 性能成本是真实存在的,但不如同步成本那么重要。不,您不需要同步对不可变结构的访问。
    • 不变性并不能保证线程安全,因为不可变对象可以具有非线程安全的可变状态。见this question
    • 您引用的问题的答案说它是线程安全的:D。它实际上。 “通过 volatile var 在线程之间交换值” - 正是我们在这里讨论的内容。
    • 不。您实际上应该假设(至少与您应该假设的一样,名为reasUser 的函数不会将您/etc/passwd 的内容写入套接字)。如果你遇到了一个不存在的实例,你应该提交一个错误。
    猜你喜欢
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-22
    • 2014-04-12
    • 2020-03-02
    相关资源
    最近更新 更多