クロージャの理解
CoddyのDartジャーニー「論理とフロー」セクションの一部。レッスン 46/65。
closure は、作成された場所の変数を、その元のコンテキストの実行が終了した後も「記憶」している特別な種類の function です。どこへ行っても、自分が生まれた場所の一部を携えている function だと考えてみてください。
ある関数の中に別の関数を作成すると、内側の関数は外側の関数の変数にアクセスできます。このアクセスが外側の関数の実行が完了した後も持続することが、これをクロージャにする要素です。
Function createGreeting(String name) {
return () {
return "Hello, $name!";
};
}この例では、createGreeting によって返される匿名関数はクロージャです。これは、周囲のスコープから name パラメーターをキャプチャします。createGreeting の実行が終了した後も、返された関数は name が何だったかを覚えています。
クロージャは、特化した関数を作成したり、状態を整理された方法で維持したりするのに非常に便利です。クロージャを使うと、作成された環境に基づいてカスタマイズされた関数を構築できるため、コードをより柔軟で強力にできます。
チャレンジ
簡単クロージャを使用して、パーソナライズされたメッセージ生成システムを構築するプログラムを作成してください。このプログラムでは、特定の情報を「記憶」し、元のコンテキストが終了した後でもその情報を使用してカスタマイズされたメッセージを生成する functions を作成します。
- 人の名前を表す文字列 input を読み取る
- 挨拶の種類(
"formal"、"casual"、または"friendly")を表す文字列 input を読み取る - 会社名を表す文字列 input を読み取る
- 名前と挨拶の種類をパラメーターとして受け取る、
createMessageGeneratorという名前の function を作成する createMessageGeneratorfunction は、次の処理を行う別の function(クロージャ)を returns する必要がある:- 会社名をパラメーターとして受け取る
- 外側の function のスコープにある名前と挨拶の種類を使用する
- 挨拶の種類に基づいて、フォーマットされたメッセージを returns する:
"formal"の場合:"Dear [name], we are pleased to welcome you to [company].""casual"の場合:"Hey [name]! Welcome to [company]!""friendly"の場合:"Hi [name], so glad you joined [company]!"- 名前と挨拶の種類の input を使って
createMessageGeneratorfunction を Call し、クロージャ function を取得する - returns されたクロージャ function を会社名の input とともに Call して、メッセージを生成する
- 以下に示す正確な形式で results を Display する
たとえば、input が "Alice"、"formal"、"TechCorp" の場合、プログラムは次のように Output する必要があります:
Message Generator System
========================
Creating message generator for: Alice
Greeting type: formal
Company: TechCorp
========================
Generated message: Dear Alice, we are pleased to welcome you to TechCorp.
Message generation completed successfullyinput が "Bob"、"casual"、"StartupXYZ" の場合、プログラムは次のように Output する必要があります:
Message Generator System
========================
Creating message generator for: Bob
Greeting type: casual
Company: StartupXYZ
========================
Generated message: Hey Bob! Welcome to StartupXYZ!
Message generation completed successfullyinput が "Carol"、"friendly"、"InnovateLab" の場合、プログラムは次のように Output する必要があります:
Message Generator System
========================
Creating message generator for: Carol
Greeting type: friendly
Company: InnovateLab
========================
Generated message: Hi Carol, so glad you joined InnovateLab!
Message generation completed successfullyプログラムでは、別の function を returns する function を作成することで、クロージャを示す必要があります。returns された function(クロージャ)は、外側の function の実行が完了した後でも、外側の function のスコープにある変数(名前と挨拶の種類)にアクセスできる必要があります。条件文を使用して、挨拶の種類の input に基づき、適切なメッセージ形式を決定してください。
自分で試してみよう
import 'dart:io';
void main() {
// 入力を読み取る
String? name = stdin.readLineSync();
String? greetingType = stdin.readLineSync();
String? company = stdin.readLineSync();
// システムヘッダーを表示する
print("Message Generator System");
print("========================");
print("Creating message generator for: $name");
print("Greeting type: $greetingType");
print("Company: $company");
print("========================");
// TODO: 以下にコードを書いてください
// Create the createMessageGenerator function that returns a closure
// 関数を呼び出してメッセージを生成する
// 最終結果を出力する
print("Generated message: \$message");
print("Message generation completed successfully");
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
論理とフローのすべてのレッスン
1リスト操作の応用
リストのプロパティ: first と lastリストの状態: isEmpty と isNotEmptyリストの反転リストへの追加: insertリストの削除: removeWhereリスト内の検索: indexOfリストのソートリストのシャッフルまとめ - リストオーガナイザー自分で練習してみよう: Dartオンラインコンパイラ