Swiftを触っていると、Rubyではお馴染みの!!
演算子を使いたくなることが度々あるので即興で作ってみました。
簡単に!!
演算子の説明をすると、オブジェクトがnil
かどうかをBool
で返してくれるようになるため、if構文などでobject != nil
の代わりに!!object
と記述できるようになります。
SwiftではObjective-Cと違い、分岐条件は論理値であることが求められるため、素直にnil
を条件としたい場合などに有用かと思います。
prefix operator !! {}
prefix func !!<T> (object: T?) -> Bool {
if let bool = object as? Bool {
return bool
}
return object != nil
}
結果
!!NSObject() // => true
!!true // => true
!!false // => false
var str1: String?
!!str1 // => false
str1 = "foo"
!!str1 // => true
この結果をさらに反転させるには!(!!NSObject())
のような書き方をしますが、気持ち悪いので!!!
演算子も定義します。
prefix operator !!! {}
prefix func !!!<T> (object: T?) -> Bool {
return !(!!object)
}
// 結果
!!!NSObject() // => false
!!!true // => false
!!!false // => true
var str2: String?
!!!str2 // => true
str2 = "foo"
!!!str2 // => false
ただ反転させてるだけです。
使用例
var array: [AnyObject]?
array?.isEmpty // => nil
!!array?.isEmpty // => false
if !!array?.isEmpty {
// arrayがnilか空の場合
}
// 同上
if array == nil || array!.isEmpty {
// arrayがnilか空の場合
}
上記の例ではarray
はnil
となっているため、2行目は通常のオプショナルチェーンなのでnil
を返します。
一方、!!
演算子をつけた場合はnil
の代わりにfalse
が返されるため、このままif文で使用できます。
テストはしていないので何かあればコメント歓迎です。
2014.11.17 追記
- プリミティブ型に対応するため引数を
AnyObject?
からAny?
に変更
2015.1.5 追記
- 引数をジェネリックス化
- 使用例を追加