Sahil Gurav
Sahil Gurav

Reputation: 135

Scala Compilation Error : Value += is not member of Int

I am at a beginner level in Scala, I am trying the following code:

var i: Int = 0

for (i <- 0 to 10) {
  if (i == 2) { 
     i += 1     
  }

  println(i)
}

When I increment i the compiler says Value += is not member of Int.

Upvotes: 11

Views: 20123

Answers (3)

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149538

You're declaring i twice, one at the outer scope and one in the inner. Your for comprehension looks at the inner i, which is a val, not a var, thus shadowing the external declaration.

Bind to a different name:

var counter: Int = 0
for (i <- 0 to 10) {
  if (i == 2) {
    counter += 1
  }

  println(counter)
}

Note you can do this without declaring an outer variable at all, using count:

val count = (0 to 10).count(i => i == 2)
println(count)

Edit:

From your comments, I understand you want to print all numbers other than 2. For that you need to negate your condition:

if (i != 2) {
  counter += 1
}

Or if you just want to filter out 2:

(0 to 10).filter(_ != 2).foreach(println)

Edit 2:

From you comments, it looks like a while loop is better for what you're trying to achieve:

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))
  }
}

But this code will run into an infinite loop since you're only incrementing i if the conditions are met. Other than that, since your doing i + 1, you might be going out of bounds if the last element equals "Banana" or "Orange", so you might want to rethink what you're doing. You'll probably run into an

Upvotes: 10

som-snytt
som-snytt

Reputation: 39577

The new error mentioned in the comment looks like:

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
              ^

It should say i instead of receiver for the simple case, where the LHS is not a complex expression, but you get the idea.

Also, nobody mentioned this:

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

Upvotes: 2

stefanobaghino
stefanobaghino

Reputation: 12804

As mentioned in Yuval's answer, you're declaring i twice. Not only that, but the inner one is implicitly immutable, therefore making it impossible for you to mutate it (that's why you get a compilation error).

To achieve the same effect you get from mutation you can use a guard in the for comprehension, like this:

for (i <- 0 to 10 if i != 2) {
  println(i)
}

This code can be seamlessly translated (and that's what the compiler actually does) to the following

(0 to 10).withFilter(i => i != 2).foreach(i => println(i))

Upvotes: 3

Related Questions