Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Updated to xcode7-beta I run across a new kind of warning. Here is my code

override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    var attributes: [UICollectionViewLayoutAttributes]? = super.layoutAttributesForElementsInRect(rect)
    if let layoutInfo = self.layoutInfo {
        attributes?.append(layoutInfo)
    }
    return attributes
}

the warning message is Variable 'attributes' was never mutated, consider changing to 'let' constant

Why does xcode say Variable 'attributes' was never mutated?

Question Update

the warning is gone when I change my code to this

override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    var attributes: [UICollectionViewLayoutAttributes]? = super.layoutAttributesForElementsInRect(rect)
    if let layoutInfo = self.layoutInfo {
        attributes!.append(layoutInfo)
    }
    return attributes
}

so forced unwrapping can take it away. But it might not be a good thing right?

like image 914
dopcn Avatar asked Jun 10 '15 03:06

dopcn


4 Answers

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!

like image 162
matt Avatar answered Oct 23 '22 12:10

matt


This has been driving me crazy too. Whenever I have a class and I change member properties, it still tells me that I should make the variable a constant. For instance:

class X { 
    var name = ""
}

var xInstance = X()
xInstance.name = "my name"

Near as I can figure, the compiler is correct. xInstance is a constant. It is assigned the pointer to the X instance during its initialization and is never assigned another value. So xInstance is constant. The class that it points to is not constant. This is more obvious in a language like C or C++ but when you realize that all class instances are really pointers to heap backed classes, this makes sense.

For those who understand C++

xInstance is equivalent to:

X *xInstance

making it a let instead means that it changes to:

X * const xInstance

I think most people would intuitively think that the swift declaration would be equivalent to

X const * xInstance
like image 23
Greg Veres Avatar answered Oct 23 '22 12:10

Greg Veres


By declaring a constant with let, you ensure that it can never be changed. This is good for making sure that you don't accidentally change it later, and it (in theory) can help the optimizer generate faster code.

If you declare a variable with var, and you don't intend to change it or call mutating methods on it, using let instead helps you enforce that contract.

like image 2
rickster Avatar answered Oct 23 '22 11:10

rickster


You have created that object as var object but value of that object not changing then after better to make it let. That's it.

As per Apple Developer Guidelines, create var object if value of that object is going to change else create let variable. Best practise

like image 1
Nilesh Patel Avatar answered Oct 23 '22 12:10

Nilesh Patel