LoginSignup
7
7

More than 5 years have passed since last update.

SwiftでもRubyの"!!"演算子を再現したい

Last updated at Posted at 2014-11-13

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か空の場合
}

上記の例ではarraynilとなっているため、2行目は通常のオプショナルチェーンなのでnilを返します。
一方、!!演算子をつけた場合はnilの代わりにfalseが返されるため、このままif文で使用できます。

テストはしていないので何かあればコメント歓迎です。

2014.11.17 追記

  • プリミティブ型に対応するため引数をAnyObject?からAny?に変更

2015.1.5 追記

  • 引数をジェネリックス化
  • 使用例を追加
7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7