【问题标题】:Scala Compilation Error : Value += is not member of IntScala 编译错误:值 += 不是 Int 的成员
【发布时间】: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


    【解决方案1】:

    您声明了两次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)
    

    编辑 2:

    从您的 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 的声明,它也会给出相同的结果,
    • 有一个 PR 可以使错误更加明确。 “不能分配给 i”或类似的。
    • @stefanobaghino 请解释一下您所说的错误是什么意思?在控制台中运行它会产生 OP 所写的内容。不多也不少。
    • 这是我通过在 Scala shell 上复制粘贴代码得到的输出:gist.github.com/stefanobaghino/9b4f0ccf9dfda156c8b640cfe435a2e1 从他的 cmets 来看,他想跳过 2,而不是打印两次。
    • @stefanobaghino 他的评论是在我回答他最初的问题几分钟后发表的,即“为什么我不能在我的变量 i 上使用 +=。在那之后,我已经编辑了我的答案,他实际上想要否定谓词,这是他在 cmets 中提出的“次要”问题。除此之外,我为他提供了一种不需要可变计数器的方法。这个答案最初是针对让他明白为什么他无法增加可变变量,我假设他的代码实际上并没有检查i != 2
    【解决方案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))
    

    【讨论】:

    • ,你的代码给了我输出 0134..9,但我对 for 循环中 i 的增量感到困惑。我不能做 i 的增量,var fruits = Array("Apple" , "香蕉", "橙子","葡萄","芒果") for( i
    • 你不能增加它,因为i 是不可变的。与其他语言中的循环不同,当您在表达式 i &lt;- 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
    • @SahilGurav 你想达到什么目的?请注意,Java 或 C++ 中使用的增加循环计数器以跳过某些元素的“技巧”可能无法逐字翻译为 scala。在 scala 中,您将使用集合操作和组合器,而不是循环和检查条件。例如,在水果集合中添加空格可以这样完成:fruits.mkString(" "),跳过第一个元素:fruits.tail,不包括一些元素fruits.filter(fr =&gt; fr != "Orange")。学习scala的时候,尽量通过函数路径进入。会更有收获。我的 2 美分。
    • 它可以用一个好的 ol'while.var i = 0; while (i &lt;= 10) { if (i == 2) i += 1; println(i); i += 1; } 翻译成 Scala
    【解决方案3】:

    评论中提到的新错误如下:

    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
    

    【讨论】:

    • 你是在告诉我,即使 -Xlint 也不会警告阴影?
    猜你喜欢
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-25
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    相关资源
    最近更新 更多