Swift4基本構文_制御文的な何か

オプショナルバインディング

型の存在の有無を冗長な書き方にしないためのif-let構文。
if letで指定したOptional型の変数がnilでなければ、構文の中でアンラップ済みの変数を使えるようにする。
ダウンキャストもif letで対応できる。


let oa = Optional("a")
if let a = oa {
	print("\(a)")
} else {
	print("nil")
}
let ob = Optional("b")
if let a = oa, let b = ob {
	print("\(a),\(b)")
} else {
	print("nil")
}
let any : Any = 1
if let iany = any as? Int {
	print("\(iany)")
}

guard,guard-let

ある関数のスコープ内で、guardで指定した条件が満たされることを保証する。
関数の先頭で引数に対してguardを定義することで引数の前提条件を書いたりする。
if-letのguard版(guard-let)もある。


func someFunc() {
    let value = 1
    guard value >= 0 else {
        return
    }
    // ここまで来たならvalueが0以上であることを保証する
    print("0以上です。")
}
func someFunc2() {
    let any : Any = 1
    guard let iany = any as? Int else {
        return
    }
    print("\(iany)")
}

nil可能な引数を取る加算関数をif,guard両方で書くと以下。
guardで書いた方が見通しがよくなる。


func add(_optionalA:Int?, _optionalB:Int?) -> Int? {
    let a: Int
    let b: Int
    if let unwrappedA = _optionalA {
        a = unwrappedA
    } else {
        return nil
    }
    if let unwrappedB = _optionalB {
        b = unwrappedB
    } else {
        return nil
    }
    return a + b
}
func add2(_optionalA:Int?, _optionalB:Int?) -> Int? {
    guard let a = _optionalA else {
        return nil
    }
    guard let b = _optionalB else {
        return nil
    }
    return a + b
}

for-in,for-case

for-inで要素の全てにアクセスする。for-caseで条件を満たす要素にアクセスする。
foreachで回す先頭で条件でスキップする奴はfor-caseで書ける。


let dict:Dictionary = ["a":1,"b":2]
for (key,value) in dict {
	print("\(key):\(value)")
}
let ary:Array = [1,2,3,4]
for case 2...3 in ary {
	print("2以上3以下")
}

fallthrough

switch文の各caseの終わりでfallthroughを書いたときに初めて後ろのcaseが実行される。
fallthroughを書かないと条件にマッチしたcaseした実行されない。
なので、switch-caseの各caseの末尾にbreakを書く必要はない。


let a = 1
switch a {
	case 1:
		print("case1")
		fallthrough
	case 2:
		print("case2")
	default:
		print("other")
}

遅延実行

関数の評価時ではなく、関数のスコープから抜けたときに実行する文を記述する。
以下、関数評価時にはgは0だが、関数がスコープから抜けたときにdeferが評価されgが1になる。


var g = 0
func someFunc2() -> Int {
    defer {
        g += 1
    }
    print("\(g)")
    return g
}
someFunc2()
print("\(g)")