Objective-Cはconst
をつけることによって、Swiftはlet
によって変わらない変数を表現できることがわかりました。
しかし変わらない変数は変えることができないが故に1回で値を設定しなければならないという大きな制約があります。
その制約が具体的にどのようなものかコードで見てみましょう。
条件つき値の設定 in Objective-C
通常のローカル変数を使った以下のようなコードがあったとします。
NSString * title;
title = getTitle();
if (title == nil) {
title = @"Default Title";
}
変数title
にまず関数getTitle()
で取得した値を設定し、その値がnil
だった場合には@"Default Title"
に設定し直しています。
このような設定処理は実際のプログラムによく現れますが、もし変数title
の値がその後変更されるものでなければ、変わらない変数として宣言して処理を行いたいところです。
書き直してみましょう。
NSString * const tempTitle = getTitle();
NSString * const title = (tempTitle != nil ? tempTitle : @"Default Title");
一時変数を別に用意し、三項演算子(?
)を用いることによってなんとか変数title
に1回で値を設定することができました。
実はこのような設定処理は気のきいたプログラミング言語においては例えば以下のように簡潔に記述することが可能です。
String title = (getTitle() || "Default Title")
これが可能になるのはOR演算子(||
)が論理値(真OR偽)を返すのではなく、真となった値(この場合は"Default Title"
)を返すタイプのプログラミング言語の場合です。
残念ながらCを親に持つObjective-Cではこの記述はできません。
条件つき値の設定 in Swift
新言語Swiftでは気のきいた記述が可能になっているかどうか早速テストしてみましょう。
let title:String = (getTitle() || "Default Title")
Swift Compiler Error: Type 'String' does not conform to protocol 'LogicValue'
残念ながらSwiftでもOR演算子は論理値を返し、Objective-Cから変わりないようです。
クロージャを用いた値の設定
Swiftでの値の設定についてドキュメントThe Swift Programming LanguageのInitializationの章にこのような例が載っています。
let someProperty: SomeType = {
// create a default value for someProperty inside this closure
// someValue must be of the same type as SomeType
return someValue
}()
値を生成するための複雑な処理をクロージャで記述し、即実行することで値を取得し設定しています。 クロージャはこのような使い方もできて便利ですね。 これが書ければSwiftで値を設定するのに困ることはなさそうです。
しかしちょっと思い出してください。 Objective-Cにもクロージャに相当するBlocksという仕組みがMac OS X 10.6以降、iOS 4以降使えるようになりました。 Blocksを用いてObjective-C版を書き直してみましょう。
NSString * const title = ^ NSString * {
NSString * const tempTitle = getTitle();
if (tempTitle != nil) {
return tempTitle;
}
return @"Default Title";
}();
見事に値を設定することができました。 この程度の複雑さですと大した恩恵はありませんが、処理が複雑になればなるほどBlocksを利用した値の設定の手法は有用になっていくでしょう。
変わらない変数についての話はこれぐらいとして、次回はまた別のテーマでSwiftを見ていきたいと思います。 ではでは。