Scala:var List vs val MutableList

Ric*_*ver 13 collections scala immutability

在Odersky等人的Scala书中,他们说使用列表.我没有阅读书籍封面,但所有的例子似乎都使用了val List.据我所知,人们也鼓励在vars上使用vals.但是在大多数应用程序中,使用var List或val MutableList之间没有权衡.显然我们可以使用val List.但是使用大量var列表(或var Vectors等)是一种好习惯吗?

我对来自C#的Scala很新.那里我有很多:

public List<T> myList {get; private set;}
Run Code Online (Sandbox Code Playgroud)

如果C#内置不变性,很容易被声明为val的集合,因为集合本身在构造之后从未改变过,即使元素在其生命周期中被添加和减去.因此,声明var集合几乎感觉就像离不变性一样.

作为对答案和评论的回应,Scala的一个强大卖点是:它可以有许多好处,而不必像Lisp或Haskell那样完全改变编写代码的方式.

Lui*_*hys 15

使用大量var列表(或var Vectors等)是一种好习惯吗?

我会说使用var不可变集合比使用val可变集合更好.在我的头顶,因为

  • 您对行为有更多保证:如果您的对象具有可变列表,您永远不会知道是否有其他外部对象要更新它

  • 你限制了可变性的程度; 返回集合的方法将产生一个不可变的方法,因此您只能在一个对象中具有可变性

  • 简单地通过简单地将其赋值给val来使var变得容易,而为了使可变集合成为不可变的,你必须使用不同的集合类型并重建它

在某些情况下,例如具有大量I/O的时间相关应用程序,最简单的解决方案是使用可变状态.在某些情况下,可变解决方案更优雅.但是在大多数代码中,您根本不需要可变性.关键是使用具有更高阶函数的集合而不是循环,或者如果不存在合适的函数则使用递归.这比听起来简单.您只需要花一些时间来了解List(以及其他大多数相同的集合)上的方法.最重要的是:

map:将提供的函数应用于集合中的每个元素 - 使用而不是循环和更新数组中的值

foldLeft:从集合中返回单个结果 - 使用而不是循环和更新累加器变量

for-yield 表达式:简化映射和过滤,尤其是嵌套循环类型问题

最终,大部分功能编程都是不变性的结果,你不可能没有另一个; 但是,本地变量主要是一个实现细节:只要它不能从本地范围中逃脱,就有一点可变性没有错.因此,使用具有不可变集合的变量,因为本地变量不是将要导出的变量.


Dan*_*ral 8

你假设要么List必须是可变的,要么指向它必须是可变的.换句话说,您需要选择以下两个选项之一:

val list: collection.mutable.LinkedList[T]
var list: List[T]
Run Code Online (Sandbox Code Playgroud)

这是一种错误的二分法.你可以两个:

val list: List[T]
Run Code Online (Sandbox Code Playgroud)

所以,你应该问的问题是我该怎么做?,但我们只能在您尝试并面对特定问题时回答这个问题.没有通用的答案可以解决你所有的问题(好吧,有 - monad和递归 - 但这普遍了).

所以试试吧.您可能有兴趣查看Code Review,其中大多数Scala问题都与如何使某些代码更具功能性有关.但是,最终,我认为最好的方法是尝试,当你无法弄清楚某些特定问题时,求助于Stack Overflow.