Swiftでarrayがnilや0件の場合に共通の処理を動作させたい時はnil結合演算子(??)を使う。
if array?.isEmpty ?? true {
// nilだったり0件だったりした時の処理
}
- arrayがnilなら、nil結合演算子がtrueを返してくれて
- arrayがnilでなく0件ならisEmptyはtrueを返してくれる
- 上の条件に当てはまらないならfalseになる
なぜ、こんな事をやるかというと、nilじゃないけど0件のときというのはoptional bindingしないといけないので、nilのときの処理と同じようにまとめるのはやりづらいから。
// 次の書き方は正しくない
if let array = array, array.isEmpty || array == nil {
// ここで呼び出したい処理がある
}
// ちなみに次のようにswitch case使ってもうまく出来ない。
switch array {
case .none, .some(array) where array.isEmpty:
// ここで呼び出したい処理がある
}
最初のコードが正しいか確かめるコードを書こう
func 確認のためのメソッドだよ(array: [Bool]?) -> String {
if array?.isEmpty ?? true {
if let array = array {
return "array.count \(array.count)"
} else {
return "arrayはnilやん"
}
}
return "何かある"
}
確認のためのメソッドだよ(array: []) // "array.count 0"
確認のためのメソッドだよ(array: nil) // "arrayはnilやん"
確認のためのメソッドだよ(array: [false]) // "何かはある"
確認のためのメソッドだよ(array: [false, true]) // "何かはある"
期待通りなんじゃないでしょうか
その他
extensionでフタをする話
念のため書くと、
上のように動作を確かめるために確認のためのメソッドだよ(array:)
というメソッドを定義しただけなので、上記のようなメソッドをUtility作ってラップしたり安易なextension作ったりすることはダサいと思う。
なぜなら、arrayがnilかもしれないという状態はそこそこ特別な状態なので、その状態であることを容認していることってそんなに無いんじゃないですかね。値を持っていないなら0件でいい場合のほうが多いので、extensionでおまじないみたいにnilを加味したりするのは嫌な感じだ。雑なextensionによってそのメソッドが乱雑に扱われるケースを多く見てきた。それよりもOptionalにするべきかどうかをしっかり考えたほうがいい。
もちろん、arrayがoptionalの場合というのは実際にはある。具体例だとUIViewのvar gestureRecognizers: [UIGestureRecognizer]?
がそれ。
こいつはiOS10のSDKでは次のように定義されている
extension UIView {
@available(iOS 3.2, *)
open var gestureRecognizers: [UIGestureRecognizer]?
こいつを見ると、Objective-C時代からあるからしょうがないやつだなとか思うんだけど、コンピューティッドプロパティを利用して、あるんならくれやっていうextensionを作るのはまあアリかなと思いました。
extension UIView {
open var ジェスチャーください: [UIGestureRecognizer] {
guard let gestureRecognizers = gestureRecognizers else {
return []
}
return gestureRecognizers
}
}
let gestures = view.ジェスチャーください