Variable 'Xxx' Was Never Mutated, Consider Changing to 'Let'

Variable 'xxx' was never mutated, consider changing to 'let'

They talked about this in the WWDC videos and the release notes.

It has always been the case that you get much, much better performance (faster speed, smaller space) if you use let instead of var whenever you can. This tells the compiler that this thing is a constant, not a variable, and that fact allows the compiler to optimize all kinds of things away.

But the compiler can't do that unless you do use let whenever you can. It won't change a var to a let for you.

Therefore, in Swift 2, the compiler does a smarter analysis at build time and warns you if you are using var where you could have used let. Eventually this feature will work properly, at which point you should take the compiler's advice!

Variable 'xxx' was never mutated; consider changing to 'let' constant ERROR

You just need to remove var, making your code:

for characteristic in service.characteristics ?? [] {
print(str)
_selectedPeripheral!.writeValue(str.dataUsingEncoding(NSUTF8StringEncoding)!, forCharacteristic: characteristic, type: CBCharacteristicWriteType.WithoutResponse)
}

because characteristic is immutable by default.

Swift 2.0: Variable was never mutated, consider changing it to let

You could search and replace all occurrences of var with let and see if that returns fewer errors.

There is no optimize functionality if that is what your are looking for.

Variable 'xxx' was never mutated; in derived class

In Swift classes and structs behave a bit differently than in C++. var and let prevent changes to the actual value, and since the variable type that you're using is a class the variable holds a reference, and not the actual data (Like Level5_encapsulation *l5message).

Since you're not mutating the value of the variable (A reference), the compiler raises a warning.

I am creating objects with var because I mutate them but I get warning: Variable 'variableName' was never mutated, consider...

Facts

  1. You are declaring avion as a local variable of the method createInitialShapeArray
  2. You are not mutating avion in the scope where it is defined
  3. avion is a Dictionary therefore a Struct (value type rules are applied)

Conclusion

There is no need to declare avion as a variable, it should be a constant.

Please note that where you write

array_shapes = [avion, ...]

you are creating a copy of avion (because it's a Dictionary).

So if you change the value inside array_shapes you are changing another value.

Therefore, at the end of the day, you are not mutating avion... and the compiler is right, it should be a constant.

Example

Please consider the following code

func foo() {
var dict = [1: "One"] // <-- Compiler warning
var anotherDict = dict
anotherDict[2] = "Two"
}

Here I am getting the same compiler warning

Variable 'dict' was never mutated; consider changing to 'let' constant

This happens because I am changing anotherDict that is not just another reference to the same value, it is actually a totally different value. This is the rule with Struct(s) and Enum(s) because they are Value Types.

Hope this helps.

I am creating objects with var because I mutate them but I get warning: Variable 'variableName' was never mutated, consider...

Facts

  1. You are declaring avion as a local variable of the method createInitialShapeArray
  2. You are not mutating avion in the scope where it is defined
  3. avion is a Dictionary therefore a Struct (value type rules are applied)

Conclusion

There is no need to declare avion as a variable, it should be a constant.

Please note that where you write

array_shapes = [avion, ...]

you are creating a copy of avion (because it's a Dictionary).

So if you change the value inside array_shapes you are changing another value.

Therefore, at the end of the day, you are not mutating avion... and the compiler is right, it should be a constant.

Example

Please consider the following code

func foo() {
var dict = [1: "One"] // <-- Compiler warning
var anotherDict = dict
anotherDict[2] = "Two"
}

Here I am getting the same compiler warning

Variable 'dict' was never mutated; consider changing to 'let' constant

This happens because I am changing anotherDict that is not just another reference to the same value, it is actually a totally different value. This is the rule with Struct(s) and Enum(s) because they are Value Types.

Hope this helps.

How to make mutability sensitive Class in Swift?

Your variable has a reference (class) type, therefore the variable only holds a reference to a class instance, and that was not mutated.

There is a big difference between a struct (a value type) and a class (a reference type). In this case you should just change the declaration to:

let myVariable = Json()

To mutate a variable with a reference type, you would have to assign a new instance, e.g.

myVariable = Json()

You seem to want value semantics for your Json type. If so, just make it a struct. For more info, see the Swift Guide

var and let definition change over swift and swift2. Is var definition changed in swift 2?

Var and Let in Swift 1.2 and 2.0 work exactly the same. var is used for a variable and let is used for a constant. While they didn't change the function itself they did add some more error handling to help in different categories, for example memory consumption. a let uses less memory than a var so why use a var when you are not changing it's value? PS: You don't have to change it. The error is the little yellow triangle and not the red circle one. Your program will compile and work as is if you leave it to var instead of let BUT it would be wiser to change it to let and that's why you get this warning.

You can also have a look here for a more in depth description of the following: stackoverflow

In swift2, is it possible to assign a tuple with 2 elements to 2 variables where one is a constant and one can be mutated

You can do this with Swift pattern matching:

while case (var x, let y)? = stack.tryPop() {
// .. x is mutated
x++

// y is not mutated
}

You can read more about Swift Patterns here.

if let warning in Swift 2.0

It means that the code never accessed / used the constant "let a" inside the if- block.

Probably you don't need the if-block at all if you do not need to access "let a". Maybe you used responseString! instead? Or do you only want to execute your code if the responseString is not nil (a simple if responseString != nil would do it then)?

After the if-block, the "let a" a will be marked for garbage collection or marked to be deleted after the if block during compile time (not sure about that).

Thus the compiler thinks that it is a good idea to replace the condition, as the assignment

let a = responseString 

will result in false if

responseString == nil

and true in all other cases.

This condition-assignment is used in 99% of the cases to assure that e.g. the nillable variable responseString is not nil or even more often to automatically unwrap it on-the-fly.



Related Topics



Leave a reply



Submit