web-dev-qa-db-ja.com

変数「xxx」は変更されていません。「let」に変更することを検討してください

xcode7-betaに更新新しい種類の警告に遭遇しました。これが私のコードです

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

警告メッセージは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
}

強制的に開封すると、それを取り除くことができます。しかし、それは良いことではないでしょうか?

15
dopcn

彼らはWWDCビデオとリリースノートでこれについて話しました。

いつでもletの代わりにvarを使用すると、はるかに優れたパフォーマンス(より速い速度、より小さなスペース)が得られるということが常にあります。これは、これが変数ではなく定数であることをコンパイラーに伝え、その事実により、コンパイラーはあらゆる種類のものを最適化できるようになります。

しかしdoができる限りletを使用しない限り、コンパイラはそれを行うことができません。 varletに変更しませんforあなた。

したがって、Swift 2の場合、コンパイラはビルド時によりスマートな分析を行い、varを使用している可能性がある場所でletを使用している場合に警告します。この機能は適切に機能します。この時点で、コンパイラーのアドバイスを受けてください。

21
matt

これも私を夢中にさせてきました。クラスがあり、メンバーのプロパティを変更した場合でも、変数を定数にする必要があることがわかります。例えば:

class X { 
    var name = ""
}

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

私が理解できる限りでは、コンパイラは正しいです。 xInstanceは定数です。初期化中にXインスタンスへのポインタが割り当てられ、別の値が割り当てられることはありません。したがって、xInstanceは定数です。それが指すクラスは定数ではありません。これは、CやC++などの言語ではより明白ですが、すべてのクラスインスタンスが実際にヒープでバックアップされたクラスへのポインターであることを理解すると、これは理にかなっています。

C++を理解している人向け

xInstanceは次と同等です。

X *xInstance

代わりにletにすることは、次のように変わることを意味します。

X * const xInstance

ほとんどの人はSwift宣言は

X const * xInstance
11
Greg Veres

letを使用して定数を宣言することにより、定数が変更されないようにします。これは、後で誤って変更しないようにするのに役立ちます。理論的には、オプティマイザがより高速なコードを生成するのに役立ちます。

varを使用して変数を宣言し、その変数を変更したり、そのメソッドで変更メソッドを呼び出したりする予定がない場合は、代わりにletを使用すると、その契約を強化できます。

2
rickster

あなたのコードは、self.layoutInfoがnilでない場合、attributesが変更される可能性があることを示唆しています

おそらく警告は、パスがself.layoutInfoをnil以外にすることにつながるため、属性はvarである必要がないことを示しています。

データがself.layoutInfoにつながる可能性がある場合、どのような条件を調べる

1
Warren Burton

あなたはそのオブジェクトをvarオブジェクトとして作成しましたが、そのオブジェクトの値は変更せずにそのままにしておきます。それでおしまい。

Apple開発者ガイドラインに従って、そのオブジェクトの値が変更される場合はvarオブジェクトを作成し、それ以外の場合はlet変数を作成します。ベストプラクティス

1
Nilesh Patel