变量'xxx'从未变异,考虑改为'让'

dop*_*pcn 15 optional swift

更新到xcode7-beta我遇到了一种新的警告.这是我的代码

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

警告信息是 Variable 'attributes' was never mutated, consider changing to 'let' constant

xcode为什么这么说Variable 'attributes' was never mutated

问题更新

当我将代码更改为此时,警告消失了

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

所以强行打开可以把它带走.但它可能不是一件好事吗?

mat*_*att 21

他们在WWDC视频和发行说明中谈到了这一点.

如果您使用let而不是var随时可以使用,那么您可以获得更好,更好的性能(更快的速度,更小的空间).这告诉编译器这个东西是一个常量,而不是一个变量,这个事实允许编译器优化各种各样的东西.

但是编译器不能这样做,除非你尽可能地使用let它.它不会改变var为a let 你.

因此,在Swift 2中,编译器会在构建时进行更智能的分析,并在您使用的var地方警告您let.最终这个功能将正常工作,此时你应该采取编译器的建议!

  • *"如果您计划添加更多代码,您实际上将更改此值"* - 该代码已存在. (4认同)

Gre*_*res 11

这也让我发疯了.每当我有一个类并且我更改成员属性时,它仍然告诉我应该使变量成为常量.例如:

class X { 
    var name = ""
}

var xInstance = X()
xInstance.name = "my name"
Run Code Online (Sandbox Code Playgroud)

接近我可以想象,编译器是正确的.xInstance是一个常量.它在初始化期间被分配了指向X实例的指针,并且永远不会被赋予另一个值.所以xInstance是不变的.它指向的类不是常数.这在C或C++这样的语言中更为明显,但当您意识到所有类实例都是指向堆支持类的指针时,这是有道理的.

对于那些了解C++的人

xInstance相当于:

X *xInstance
Run Code Online (Sandbox Code Playgroud)

使它成为let代替意味着它变为:

X * const xInstance
Run Code Online (Sandbox Code Playgroud)

我想大多数人会直觉地认为快速宣言相当于

X const * xInstance
Run Code Online (Sandbox Code Playgroud)

  • 这对像我这样的古老化石来说意义重大.let为您提供一个指向变量对象的常量指针.这里有一个有趣的皱纹......如果你声明一个结构而不是一个类,整个结构将是不可变的/常量. (4认同)