問題の歴史: トレーリングクロージャ構文は、Swiftで導入された構文形式で、関数の最後にクロージャブロックを使用する際にコードの可読性を向上させるために作られました。特に機能型および宣言型スタイルでは、大きな入れ子のクロージャの操作を簡素化します。
問題: 多数の括弧を伴う標準的なクロージャの宣言は、コードの視覚的な構造を複雑にし、理解しにくくします:
UIView.animate(withDuration: 0.3, animations: { ... })
クロージャのサイズが増すにつれて、このコードはより読みづらくなります。
解決策: Swiftでは、最後の引数である関数を括弧の外に出すことが可能です:
UIView.animate(withDuration: 0.3) { // アニメーションブロック }
クロージャが2つ以上ある場合、トレーリングクロージャ構文は最後のクロージャパラメータにのみ適用でき、他のパラメータは丸括弧内で指定する必要があります。
主な特徴:
クロージャが関数の最後のパラメータでない場合でもトレーリングクロージャ構文を使用できますか?
いいえ、最後のパラメータのみがトレーリングクロージャとして記述できます。複数のクロージャが必要な場合、最後のものだけを括弧の外に出し、他のものは丸括弧内で渡す必要があります。
func fetch(url: String, completion: () -> Void, onError: () -> Void) fetch(url: "...", completion: { ... }) { // onError }
1つのクロージャ引数を持つメソッドを呼び出す際に丸括弧を省略できますか?
はい、関数が唯一の引数としてクロージャを受け取る場合、丸括弧を完全に省略することができます:
func doWork(action: () -> Void) doWork { print("作業") }
クロージャの後に可変長引数を持つ関数にトレーリングクロージャを使用できますか?
いいえ、トレーリングクロージャ構文は、クロージャが最後の引数である場合にのみ適用されます。その後に可変長引数や他の引数を置くことはできません。次のように呼び出すとエラーが発生します:
func test(x: () -> Void, y: Int...) // ... トレーリングクロージャを使用した呼び出しは不可能
2つのクロージャパラメータを伴う呼び出しがトレーリング構文なしで行われると、メソッドが縦に5画面を占め、理解の難易度が上がります。
利点:
欠点:
UICollectionViewCompositionalLayoutの実装ではトレーリングクロージャが使用されており、レイアウトブロックは簡単に読み取れるため、構造がレイアウトコンポーネントの階層を視覚的に示しています。
利点:
欠点: