LoginSignup
28
28

More than 5 years have passed since last update.

Swiftで条件式にOptional型が渡せる仕組みを調べた

Last updated at Posted at 2014-07-22

2014/08/06 追記

この記事の内容は古くなりました。

Xcode6 Beta5からはLogicValueBooleanTypeに変更されました。
また、Optional型はBooleanTypeに準拠しなくなったため、以下はコンパイルエラーになるようになりました。

let str: String? = "あいうえお"

if str { // コンパイルエラー
    println("str=\(str)")
}

まだImplicitlyUnwrappedOptionalの方はBooleanTypeに準拠しているようですが...

はじめに

※TwitterやQiitaで疑問に感じられている方がいらっしゃるようなので、日頃薄々感づいていた事と憶測をミックスしてお送りします。

  • Xcode6 beta4

Swiftでは条件式の結果は論理値にする必要がある

Swiftにおいて、ifやwhile、三項演算子の条件式の結果は、Bool値にしないとコンパイルが通らなくなりました。

let i = 1

if i { // コンパイルエラー
    println("true")
}

if i != 0 { // こっちはOK
    println("true")
}
Playground execution failed: error: <EXPR>:10:4: error: type 'Int' does not conform to protocol 'LogicValue'

で、これはそういう物なんだと覚えておいて、いざ次のようなコードに出会うと「えっ??」ってなると思います。

let str: String? = "あいうえお"

if str {
    println("str=\(str)")
}
実行結果
str=Optional("あいうえお")

Bool値じゃないのに何で??

Swiftで条件式を評価するカラクリ

Swiftでは条件式の結果値の型が、LogicValueプロトコルに準拠(実装)している必要があります。

LogicValueプロトコル
protocol LogicValue {
    func getLogicValue() -> Bool
}

ご覧の通り、getLgicValue()という関数が一つだけ定義されています。

ifなどの条件式では、条件式の結果の値に対して、この関数を呼び出し、その戻り値がtrueかどうかを評価しているようなのです。

Bool型もこの関数を実装しています。

extension Bool : LogicValue {
    func getLogicValue() -> Bool
    init(_ v: LogicValue)
}

おそらくreturn selfしているだけでしょう。

Optional型についても、この関数を実装しています。

enum Optional<T> : LogicValue, Reflectable, NilLiteralConvertible {
    ()
    /// Allow use in a Boolean context.
    func getLogicValue() -> Bool
    ()
}

おそらくreturn self != nilだとか"Noneじゃない"だとかそういう事が実装されているんだと思います。

というわけで、条件式は「論理値で判断している」、もっと詳しく言えば「getLogicValue()の結果で判断している」という事ですね。
これがOptional型でもエラーにならないワケです。

諸先輩方に怒られそうな実装

LogicValueプロトコルにさえ準拠していれば良いので、やろうと思えばObjective-C(C言語)の時みたいな事もできます。

extension Int : LogicValue {
    public func getLogicValue() -> Bool {
        return self != 0
    }
}

let i = 1

if i { // ←これ
    println("true")
}
実行結果
true

こういったC言語風の書き方が出来なくなっているのには理由が有ると思いますのでオススメはしません。
何故か、という事情は詳しくありませんのでどなたか教えてください。
(C#など他の言語でも論理値を強制されるものがありますね。)

28
28
3

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
28
28