Scala瓦尔和var与集合

r3i60tvu  于 2023-08-05  发布在  Scala
关注(0)|答案(2)|浏览(137)

我想更好地理解以下问题。什么时候应该使用var,什么时候使用瓦尔?
我知道Scala中有一条经验法则,我们应该使用瓦尔。
对于基本类型来说很简单--我们应该只在循环中改变变量时才使用var。
我的第一个问题是,在Scala中是否有更好的方法来做到这一点:

var sum = 0
while (condition) sum = sum + something
return sum

字符串
但同样和更复杂的是集合。
1.我们有可变集合和不可变集合
1.我们有var和瓦尔作为指针。

我想问以下每一个是否有意义(手段可能是,但不一定是好的做法),以及我们应该何时使用以下每一个选项(什么是好的做法)

1.瓦尔可变集合

  1. var可变集合
    1.瓦尔不可变集合(不能是)
  2. var不可变集合

我还想问一下,改变一个集合是否意味着改变它的指针或元素,或者两者都改变。举一个列表为例。如果我添加一个元素,我就做了一个改变。但是如果我只想更新一个元素呢?

我问这个问题的原因是,当我们需要解决常见问题时,我们需要改变集合,我们不能使用不可变的瓦尔。

var list = List(1,2,3)
// this will not save the list with changes
while (condition) list :+ some_integer
return list


这个主题在Scala中让我感到困惑。
如果有人能把这个主题说得更清楚一点,我会很感激。- 谢谢-谢谢
我想更好地理解这个主题。在其他语言中,这是非常清楚的,但在Scala中,这有点令人困惑。

0h4hbjxa

0h4hbjxa1#

在您的示例代码中:

var sum = 0
while (condition) sum = sum + something
return sum

字符串
如果没有var,如何做到这一点实际上取决于condition是什么。我们不能给予你一个放之四海而皆准的答案。
但我会给予你们一个具体的例子。假设我们有一个命令式方法getNext(),它返回一个Int,我们想在它返回一个-1时停止求和。在Java中,可以这样写:

int sum = 0;
int next;
while ((next = getNext()) != -1) {
  sum += next;
}
return sum;


在Scala中,我会这样写:

Iterator.continually(getNext())
  .takeWhile(_ != -1)
  .sum


这里我使用了高阶方法,如continuallytakeWhile。如果问题的形式不同,不同的高阶方法可能是正确的。
顺便说一句,注意我没有使用return。99%的Scala代码根本不使用return

yzxexxkh

yzxexxkh2#

这是我开始学习Scala时的痛苦。所以,我明白你的想法。简短的回答:valimmutable集合,并在每次要更改它时创建一个新副本。
过度简化:对于一个不可变的对象或集合,当你想要进行更新时,你(或底层的语言)会创建一个该集合的副本。新副本将与旧集合或对象共享未更改的数据。因此,它具有内存效率。因为集合是不可变的,并且该集合中的所有内容(指针)都指向不可变的内容。你应该安全地引用这些引用,因为你知道你所引用的内容不会改变。
因此,使用val构建Scala代码的方式与使用var.构建Scala代码的方式不同,由于这种差异,您给出的代码片段将不会以这种方式编写。我不知道你想达到什么目的,所以我很难重写它。
假设你想在列表中添加someInteger,如果一个条件适用于列表中的所有元素。

val newList = if (list.forall(elem => elem > 4)) list :+ someInteger else list

字符串
这里重要的是,你有一个新的列表,你会返回。
由于有丰富的集合和所有的方法,在Scala代码中通常看不到传统的while和for循环。在某些情况下,你可能会看到递归。
请允许我再给予一个例子

case class Account(value: Int){
  def deposit(amount: Int): Account = {
    this.copy(value = this.value + amount)
  }
}

val account = Account(0)
val updatedAccount = account.deposit(10)


此示例说明了两件事:
1.更新帐户值需要帐户的副本,因为value是不可变的。
1.您需要一个新的val updatedAccount来存储更新的帐户。
这是你通常在Scala中编写代码的方式。
最后,让我们浏览一个账户列表,关闭任何余额低于零的账户

val updatedAccounts = accounts.map(account => if (account.value <0) account.close else account)


在上面的所有例子中,我们都使用了带有不可变集合的val。我希望这是有帮助的。

相关问题