判定する値がBoolの場合
例えばある値がtrueかfalseかで設定する文字列を変えたいって場合、if elseで素直に分けるか三項演算子が使えます。この場合はとても簡単です。
if elseでやる
Swift1.2からif elseで必ず値が設定されるならば、letで宣言時に値を代入しなくてもコンパイルエラーにならなくなりました。
let result: String
if success {
result = "OK"
} else {
result = "NG"
}
三項演算子
もっとすっきり書きたいとき。三項演算子は賛否両論ありますが、これぐらい単純なやつは三項演算子の方が簡潔で意図が伝わりやすいと思います。
let result = success ? "OK" : "NG"
Optionalな値が存在するかどうかで分けたい
こっちが本題です。ある値がOptionalな値で値が存在する場合は、その値を使って文字列を生成して、nilの場合はデフォルトっぽい文字を設定したいみたいな場合にSwiftっぽくどう書けるかという話です。
if let 使う場合
正しいやり方なんですが、まぁーちょっと長いですね。
let info: Info? = nil
let result: String
if let info = info {
result = "\(info.title):\(info.value)"
} else {
result = "-"
}
三項演算子
まず、Optinalな値はBoolにならないのでそのままでは、三項演算子の条件部分には書けません。
let info: Info? = nil
let result = info ? "" : "" // => compile error
Optionalな値は!= nil
で判定することもできるので三項演算子の条件部分に書けます。そもそもnil
かどうかって書くのがいけてないのと、使うときに!
でForce Unwrappingしなきゃいけなくて綺麗じゃないですね。
let info: Info? = nil
let resutl = (info != nil) ? "\(info!.title):\(info!.value)" : "-"
変数のGetterを利用
これが一番Swiftっぽいかなと思います。var
で宣言してるけど、Getterしか書いてないから、あとから代入もできないです。
let info: Info? = nil
var result: String {
if let info = info {
return "\(info.title):\(info!.value)"
} else {
return "-"
}
}
result = "hoge" // => compile error
追記
もっといい方法ありました。
mapを使う
@taketo1024 さんに教えてもらいました。これが一番いいですね!
let result = info.map { "\($0.title):\($0.value)" } ?? "-"