Posted at

条件式のカンマについて(Swift)


はじめに

私が実際にやってしまった失敗です。

SwiftLintでUnused Optional Bindingのルールに引っかかり、以下のように修正しました。

- guard let _ = foo, let _ = bar else {

+ guard foo != nil || bar != nil else {
return
}

こちらの修正に何の疑問も抱かない方は、 本記事を最後まで読むことをおすすめします

すぐに気づいた方は、本記事を読まなくても大丈夫です。


結論

先に結論を述べます。

Swiftの条件式において、,&& は同義 なので、先ほどの修正は以下が正しいです。

- guard let _ = foo, let _ = bar else {

+ guard foo != nil && bar != nil else {
return
}


証明

簡単なPGを組み、上記の結論を証明します。

func exampleBefore(foo: Int?, bar: String?) -> Bool {

guard let _ = foo, let _ = bar else {
return false
}
return true
}

func exampleAfter(foo: Int?, bar: String?) -> Bool {
guard foo != nil && bar != nil else {
return false
}
return true
}

exampleBefore(foo: nil, bar: nil) // false
exampleBefore(foo: 1, bar: nil) // false
exampleBefore(foo: nil, bar: "example") // false
exampleBefore(foo: 1, bar: "example") // true

exampleAfter(foo: nil, bar: nil) // false
exampleAfter(foo: 1, bar: nil) // false
exampleAfter(foo: nil, bar: "example") // false
exampleAfter(foo: 1, bar: "example") // true

このPGをプレイグラウンドで実行してみます。

スクリーンショット 2019-04-04 18.09.20.png

exampleBeforeexampleAfter の戻り値が同じになり、先ほどの結論が正しいことを証明できました。


おまけ

条件式に , を多用すると可読性が落ちることがあるため、if-letまたはguard-let文以外では使わない方がいいと思いました。