【发布时间】:2017-01-16 20:36:40
【问题描述】:
我是 Scala 的初学者,我正在尝试以下代码:
var i: Int = 0
for (i <- 0 to 10) {
if (i == 2) {
i += 1
}
println(i)
}
当我增加i 时,编译器会显示Value += is not member of Int。
【问题讨论】:
标签: scala
我是 Scala 的初学者,我正在尝试以下代码:
var i: Int = 0
for (i <- 0 to 10) {
if (i == 2) {
i += 1
}
println(i)
}
当我增加i 时,编译器会显示Value += is not member of Int。
【问题讨论】:
标签: scala
您声明了两次i,一次在外部作用域,一次在内部作用域。您的 for 理解会查看内部 i,它是 val,而不是 var,因此会影响外部声明。
绑定到不同的名称:
var counter: Int = 0
for (i <- 0 to 10) {
if (i == 2) {
counter += 1
}
println(counter)
}
请注意,您可以使用count:
val count = (0 to 10).count(i => i == 2)
println(count)
从您的 cmets 得知,您希望打印除 2 之外的所有数字。为此,您需要否定您的条件:
if (i != 2) {
counter += 1
}
或者如果你只是想过滤掉 2:
(0 to 10).filter(_ != 2).foreach(println)
从您的 cmets 看来,while 循环更适合您想要实现的目标:
var i = 0
while (i < fruits.length) {
if (fruits(i) == "Banana") {
i += 1
println(i + " " + fruits(i))
} else if (fruits(i) == "Orange") {
i += 1
println(i + " " + fruits(i))
}
}
但此代码将陷入无限循环,因为您仅在满足条件时才递增 i。除此之外,因为你在做i + 1,如果最后一个元素等于“香蕉”或“橙色”,你可能会越界,所以你可能想重新考虑你在做什么。你可能会遇到一个
【讨论】:
i 上使用 +=。在那之后,我已经编辑了我的答案,他实际上想要否定谓词,这是他在 cmets 中提出的“次要”问题。除此之外,我为他提供了一种不需要可变计数器的方法。这个答案最初是针对让他明白为什么他无法增加可变变量,我假设他的代码实际上并没有检查i != 2。
正如 Yuval 的回答中提到的,您声明了两次 i。不仅如此,内部的也是隐式不可变的,因此你不可能改变它(这就是你得到编译错误的原因)。
为了达到与突变相同的效果,您可以在 for 理解中使用守卫,如下所示:
for (i <- 0 to 10 if i != 2) {
println(i)
}
这段代码可以无缝翻译(编译器实际上就是这样做的)到下面的
(0 to 10).withFilter(i => i != 2).foreach(i => println(i))
【讨论】:
i 是不可变的。与其他语言中的循环不同,当您在表达式 i <- 1 to 10(称为 generator)中声明 i 时,您正在从右侧的表达式中“提取项目”(1 to 10 恰好是方法调用1.to(10),它返回一个从1到10的范围)。如果您熟悉 Java,请将其视为 for each 而不是 for-each 循环。在这里您可以找到更多关于 for-comprehensions 在 Scala 中的信息:docs.scala-lang.org/tutorials/tour/sequence-comprehensions.html
fruits.mkString(" "),跳过第一个元素:fruits.tail,不包括一些元素fruits.filter(fr => fr != "Orange")。学习scala的时候,尽量通过函数路径进入。会更有收获。我的 2 美分。
while.var i = 0; while (i <= 10) { if (i == 2) i += 1; println(i); i += 1; } 翻译成 Scala
评论中提到的新错误如下:
scala> :pa
// Entering paste mode (ctrl-D to finish)
var i: Int = 0
for(i <- 0 to 10)
{
if (i == 2)
{
i += 1
}
println(i)
}
// Exiting paste mode, now interpreting.
<pastie>:19: error: value += is not a member of Int
Expression does not convert to assignment because receiver is not assignable.
i += 1
^
对于 LHS 不是复杂表达式的简单情况,应该说 i 而不是 receiver,但你明白了。
另外,没有人提到这一点:
scala> :pa
// Entering paste mode (ctrl-D to finish)
object X {
var i: Int = 0
for(i <- 0 to 10)
{
if (i == 2)
{
this.i += 1
}
println(this.i)
}}
// Exiting paste mode, now interpreting.
defined object X
scala> X
0
0
1
1
1
1
1
1
1
1
1
res3: X.type = X$@1129829c
【讨论】: