考え事をしながら歩いていて電柱にぶつかったことがあります。ちょっと色々自信を失いかけました。株式会社メモリアインクのふくしまです!
今回は、Swiftにおけるクロージャー(無名関数)について解説していきます!
この記事を読んで分かること…
・クロージャって何?
・クロージャを使うとどんないいことがあるの?
・クロージャの基本的な使い方
・クロージャの応用
クロージャ(無名関数)の基礎
クロージャ(無名関数)ってなに?
Swiftにおけるクロージャとは、「無名関数」と呼ばれており、自己完結型の何かしらの処理をコードブロック({ }
)で記述するためのSwiftの機能の一つです。
…って言われても、あまりイメージつかないかもしれませんが、徐々に紐解いていきますのでご安心ください!
とりあえず最初のうちは、「何かしらの処理の塊」= クロージャ(無名関数)ぐらいのイメージで大丈夫です。
メソッド(関数)と何が違うの?
「何かしらの処理」と聞くと真っ先にメソッド(関数)を思いつくかと思いますが、そのメソッド(関数)との違いはなんなのでしょうか?
クロージャ(無名関数)とメソッド(関数)の構文を見比べるとその違いが理解できると思います!
🔸メソッド(関数)の構文
func 関数名(引数) -> 戻り値の型 {
// コードブロック
}
🔸クロージャ(無名関数)の構文
{ (引数) -> 戻り値の型 in
// コードブロック
}
メソッド(関数)の定義では、関数名を定義した上で、コードブロック内で処理を書きます。
定義したメソッドは、関数名()で呼び出し元から呼び出します。
一方で、クロージャはいきなりコードブロック内で処理を書き始めます。このことから”関数名を持たない処理”という意味で「無名関数」と呼ばれています。
関数名を持たないことで、処理自体を変数に格納したりメソッド(関数)の引数にすることができるのがクロージャの特徴と言えます。
クロージャの基本的な使い方
それでは実際に、配列のsort
メソッドをクロージャーを使用してカスタマイズする例を使ってクロージャの使い方について学びましょう!sort
メソッドは、配列の中身の順番を降順・昇順に入れ替えてくれるSwift標準のメソッドです。
var numbers = [20, 10, 40, 30]
numbers.sort(by: <)
print(numbers)
出力結果:
[10, 20, 30, 40]
▲sort
メソッドの引数by:
に比較演算子を入れることで、内部でよしなに配列Arrayの中身を見て並び替えてくれる便利なメソッドですが、今回はこちらの引数をあえてクロージャーで書いてsort
メソッドをカスタムしてみます。
var numbers = [20, 10, 40, 30]
numbers.sort(by: { (number1: Int, number2: Int) -> Bool in
return number1 < number2
})
▲sort
メソッドの引数にクロージャーを指定しています。
クロージャーの部分を抜き出してみましょう。
{ (number1: Int, number2: Int) -> Bool in
return number1 < number2
}
// クロージャ(無名関数)の構文
{ (引数) -> 戻り値の型 in
// コードブロック
}
クロージャ部分の説明:
・引数:(number1: Int, number2: Int)
sort
メソッドが呼び出された時、配列の値が入ってきます。
・戻り値の型:-> Bool
このクロージャーの戻り値がBooean型(true
かfalse
かの論理演算子)を返すことを宣言します。
・in
キーワード
引数、戻り値の定義の完了と処理の始まりを示します。
inキーワード以降に実際の処理を定義します。
・処理:return number1 < number2
第一引数と第二引数の値を比較して、trueかfalseで返します。
処理が実行されるタイミングは、sort
メソッドが呼び出され、引数に値がセットされた瞬間です。
非同期処理
Swiftの非同期処理では、処理が完了した後の動作をクロージャとして定義することがよくあります。
// 非同期処理の定義
func fetchData(completion: @escaping (Data?, Error?) -> Void) {
// ...
// 非同期処理でデータをフェッチする処理
// ...
completion(fetchedData, nil)
}
// 非同期処理(@escaping属性のついたクロージャ)完了後の処理
fetchData { data in
print("非同期処理の結果: \(data)")
}
この例では、fetchData
関数は非同期にデータを取得し、完了時にクロージャを呼び出します。このクロージャはデータとエラー情報をパラメータとして受け取ります。@escaping
は、クロージャが関数の引数として渡される際に使用される属性です。この属性は、クロージャが関数のスコープを超えて後で実行される可能性がある(例:非同期処理)ことを示します。
非同期処理が完了し、completion(fetchedData, nil)
が呼ばれると、fetchData
関数の呼び出し先に定義した非同期後の処理を呼び出します。
クロージャの利点と欠点
利点
- コードの簡潔性: クロージャを使用することで、関数やメソッドの引数として直接コードブロックを記述でき、コードが読みやすくなります。
- 柔軟性: クロージャはパラメータと戻り値を持つことができ、非同期処理やコールバック処理において高い柔軟性を発揮します。
欠点
- キャプチャリストの複雑さ: クロージャが外部の変数をキャプチャする際、メモリ管理に注意が必要です。特に、循環参照が発生するとメモリリークの原因になり得ます。
- 読みづらさ: 短いクロージャは便利ですが、長いクロージャや複雑なロジックを含むクロージャは読みづらくなることがあります。
まとめ
Swiftにおけるクロージャの使い方を理解し、適切に活用することで、より効率的で読みやすいコードを書くことができます。少々複雑ですが、何回も記事を読んで理解しておきましょう!
この記事が皆様の開発ライフの一助になれれば幸いです!
この記事があなたのスキルアップに役立ったなら、次のキャリアステップを踏み出す絶好の機会かもしれません。エンジニアとしてのさらなる成長と挑戦を求めるなら、
未経験からIT・Webエンジニアを目指すなら【ユニゾンキャリア】
コメント
コメント一覧 (2件)
[…] 【iOS】Swiftにおけるクロージャ(無名関数)について徹底的に解説 […]
[…] あわせて読みたい 【Swift】クロージャ(無名関数)の基本とクロージャを使った非同期処理につ… […]