Swift1.2でif letでの複数の宣言が可能になった
func getA()->String?{
return "A"
}
func getB()->String? {
return "B"
}
func getC()->String?{
return "C"
}
func test() -> (){
// カンマ区切りで複数の変数のOptional判定 + 宣言が可能に
if let a = getA(), b = getB(), c = getC(){
print( a + b + c + "のすべてがnilではない ")
}else{
print( "a,b,cのうちどれかがnilの場合はfalse")
}
}
if letの複数宣言では直前に解決した変数を使うことができる
func getA()->String?{
return "A"
}
func getB(a:String)->String? {
return a + "B"
}
func getC(b:String)->String?{
return b + "C"
}
func test() -> (){
if let a = getA(),
b = getB(a), // ←直前に解決したaを引数として使用
c = getC(b) // ←直前に解決したbを引数として使用
{
print( a + b + c + "のすべてがnilではない ")
}else{
print( "a,b,cのうちどれかがnilの場合はfalse")
}
}
つまりこれは
getA()
getB(a)
getC(c)
と逐次処理をして途中でnilが返されると処理を中断するような
簡易的な例外処理として機能する
例えばこれをSwift1.1の範疇で書こうとすると
if文のネストが深くなりめんどくさい
func test() -> (){
if let a = getA(){
if let b = getB(a) {
if let c = getC(b) {
print( a + b + c + "のすべてがnilではない ")
return
}
}
}
print( "a,b,cのうちどれかがnilの場合はfalse")
}
if letの中で処理を書いてしまえ
いくつかユーティリティ的な関数を用意すると、if letの中で通常と処理と同じ実装を行うことができる
簡単な制御用関数
// if letのなかではOptional型しか扱えないので、
// 通常の変数を扱うためにOptional型でくるんでやる
func let_<T>(s:T) -> T?{
return s
}
// if文に相当する分岐
func if_<T>(b:Bool, #then:()->T, #els:()->T) -> T{
if b {
return then()
}else{
return els()
}
}
// あとはfor文に相当する処理とか
func getC(c:String) -> String? {
return c + "C"
}
func test(arg:String) -> String? {
if let
a = let_(arg), // 引数をoptional化
b = if_(a == "A", // 条件分岐
then:{
return a + "B"
},els:{
return nil
}),
c = getC(b)
{
return c
}
return nil
}
test("A") // => "ABC"
test("B") // => nil
これってHaskell的には
Maybeモナドのdo構文とそっくりですね