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
- You are declaring
avion
as a local variable of the methodcreateInitialShapeArray
- You are not mutating
avion
in the scope where it is defined avion
is aDictionary
therefore aStruct
(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
- You are declaring
avion
as a local variable of the methodcreateInitialShapeArray
- You are not mutating
avion
in the scope where it is defined avion
is aDictionary
therefore aStruct
(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 astruct
. 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
Padding a Swift String for Printing
Programmatically Navigate to New View in Swiftui
In Swift, How to Convert a String to an Enum
Can the Height of the Uisearchbar Textfield Be Modified
Swift: Property Conforming to a Specific Class and in the Same Time to Multiple Protocols
How to Create Dictionary That Can Hold Anything in Key? or All the Possible Type It Capable to Hold
What's the Difference Between Aranchor and Anchorentity
Do Swift Inner Classes Have Access to Self of Outer Class
Add "For In" Support to Iterate Over Swift Custom Classes
How to Convert Timeinterval into Minutes, Seconds and Milliseconds in Swift
How to Override Trait Collection for Initial Uiviewcontroller? (With Storyboard)
How to Get Directory Size with Swift on Os X
Class 'Viewcontroller' Has No Initializers in Swift
Convert Avaudiopcmbuffer to Nsdata and Back
Hide/Show Tab Bar When Push/Back. Swift
Swiftui. How to Change the Placeholder Color of the Textfield