この記事は何
Swift Dcumentationより、defer
ステートメントを解説する。
Swiftを基礎から学ぶには
自著、工学社より発売中の「まるごと分かるSwiftプログラミング」をお勧めします。変数、関数、フロー制御構文、データ構造はもちろん、構造体からクロージャ、エクステンション、プロトコル、クロージャまでを基礎からわかりやすく解説しています。
また、Swiftプログラミングを基礎から動画で学びたい方には、Udemyコース「今日からはじめるプログラミング」をお勧めします。
遅延ブロックを作成する
コードが実行されるかどうかを制御するif
や実行の回数を制御するwhile
などのフロー制御構文とは異なり、defer
ステートメントはコードの実行を遅延します。
作成した遅延ブロックのコードは、プログラムが現在のスコープを終了したときに実行されます。
var score = 1
if score < 10 {
defer { print(score) } // スコープ終了の直前に実行される
score += 5
}
// Prints "6"
この例では、if
ステートメントのボディを終了する直前に、defer
ブロックのコードが実行されます。
まず、if
ステートメントのコードが実行されて、スコアに5
を加算します。
そして、if
ステートメントのスコープを終了する直前に遅延ブロックが実行されて、スコアを出力します。
遅延ブロックの利点
プログラムがそのスコープをどのように終了(例えば、関数からの早期終了、break
によるfor
ループからの脱出、エラーのスローなど)しても、defer
ブロックは実行されます。
この仕組みは、defer
は開始と終了のペア・アクション(例えば、手動でのメモリ割り当てと解放、低レベルなファイル記述子による開閉、データベース・トランザクションの開始と終了など)が発生することを保証する必要がある操作で役立ちます。
開始と終了の両アクションを並べてコーディングできるからです。
次のコードは、コードのチャンク内で100
を加算および減算することで、スコアに一時的なボーナスを与えます。
var score = 3
// スコアが100未満なら、一時的なボーナスを加算
if score < 100 {
score += 100 // ボーナスを加算したら...
defer { score -= 100 } // 直後で、忘れずに減算を遅延しておく
/* 以降の行では、ボーナスが加算されている */
print(score)
}
/* ボーナスは解除されている */
print("Out of bonus; \(score)")
// Prints "103"
// Prints "Out of bonus; 3"
遅延ブロックの実行される順番
同じスコープに複数の遅延ブロックがある場合、先のブロックの方が後に実行されます。
var score = 1
if score < 10 {
defer { print(score) } // 最初のdeferブロックは最後に実行される
defer { print("The score is:") } // 先に実行されるdeferブロック
score += 5
}
// Prints "The score is:"
// Prints "6"
ランタイムエラーやクラッシュなどによってプログラムが停止した場合、遅延コードは実行されません。
ただし、遅延コードはエラーがスローされると実行されます。
エラー処理で遅延を使用する方法については、「クリーンアップアクションの指定」を参照してください。