関数を引数として渡す
CoddyのDartジャーニー「論理とフロー」セクションの一部 — レッスン 45/65。
プログラミングにおいて、関数は数値や文字列のような単純な値を受け取るだけでなく、他の関数をパラメータとして受け取ることもできます。この強力な概念は高階関数(higher-order function)と呼ばれ、柔軟で再利用可能なコードを書くための全く新しい方法を切り開きます。
関数を引数として渡すとき、本質的には別の関数に対して、どの操作を実行するかを決定する能力を与えていることになります。これは、誰かに道具を渡し、それをさまざまな素材に対してどのように使うかをその人に選ばせるようなものだと考えてください。
void processNumbers(List<int> numbers, Function operation) {
for (int number in numbers) {
operation(number);
}
}この例では、processNumbers はリストと関数をパラメータとして受け取ります。関数パラメータである operation は、整数を受け取る任意の関数にすることができます。つまり、数値を表示したり、2倍にしたり、その他必要な操作を実行したりする関数を渡すことができます。
このアプローチにより、コードの柔軟性が非常に高まります。考えられるすべての操作に対して個別の関数を記述する代わりに、操作をパラメータとして受け取ることで、多くの異なる操作に対応できる1つの関数を記述します。
チャレンジ
簡単柔軟な数値プロセッサを構築することで、関数を引数として渡すデモンストレーションを行うプログラムを作成してください。このプログラムでは、異なる処理関数を作成し、それらを数値のリストに操作を適用するメインのプロセッサ関数に渡します。
- カンマで区切られた数値を含む文字列入力を読み取ります(例:
"1,2,3,4,5") - 操作タイプを表す文字列入力を読み取ります(
"double"、"square"、または"increment") - 最初の入力を文字列のリストに分割し、それぞれを整数に変換します
- 3つの個別の関数を作成します:
doubleNumber- 整数を受け取り、それを2倍にして返しますsquareNumber- 整数を受け取り、それを自身と掛け合わせて返しますincrementNumber- 整数を受け取り、それに1を足して返しますprocessNumbersという名前のメイン関数を作成します。これは整数のリストと関数をパラメータとして受け取りますprocessNumbers関数は、リスト内の各数値に指定された関数を適用し、その結果を含む新しいリストを返す必要があります- 操作タイプの入力に基づいて、適切な関数を
processNumbersに渡します - 以下の形式で結果を表示してください
例えば、入力が "2,4,6,8" と "double" の場合、プログラムは次のように出力する必要があります:
Number Processor
================
Original numbers: [2, 4, 6, 8]
Operation: double
Processing numbers...
Result: [4, 8, 12, 16]
Operation completed successfully入力が "3,5,7" と "square" の場合、プログラムは次のように出力する必要があります:
Number Processor
================
Original numbers: [3, 5, 7]
Operation: square
Processing numbers...
Result: [9, 25, 49]
Operation completed successfully入力が "10,20,30" と "increment" の場合、プログラムは次のように出力する必要があります:
Number Processor
================
Original numbers: [10, 20, 30]
Operation: increment
Processing numbers...
Result: [11, 21, 31]
Operation completed successfullyプログラムは、3つの操作関数のうちの1つを引数として processNumbers 関数に渡すことで、高階関数の概念を実証する必要があります。条件文を使用して、操作タイプの入力に基づいてどの関数を渡すかを決定してください。processNumbers 関数は、入力リストを反復処理し、各要素に指定された関数を適用し、その結果を新しいリストに収集する必要があります。
チートシート
高階関数は、他の関数をパラメータとして受け取ることができる関数であり、柔軟で再利用可能なコードを可能にします。
関数を引数として渡すには、Function 型のパラメータを定義します。
void processNumbers(List<int> numbers, Function operation) {
for (int number in numbers) {
operation(number);
}
}これにより、同じデータに対してさまざまな操作を実行するために異なる関数を渡すことができるようになり、コードがよりモジュール化され、考えられるすべての操作に対して個別の関数を記述する必要がなくなります。
自分で試してみよう
import 'dart:io';
void main() {
// 入力を読み込む
String? numbersInput = stdin.readLineSync();
String? operation = stdin.readLineSync();
// 文字列の入力を整数のリストに変換する
List<int> numbers = numbersInput!.split(',').map((e) => int.parse(e.trim())).toList();
// TODO: 3つの操作関数(doubleNumber, squareNumber, incrementNumber)を作成する
// TODO: リストと関数をパラメータとして受け取る processNumbers 関数を作成する
// TODO: 条件文を使用して、操作タイプに基づいて渡す関数を決定する
// TODO: 適切な関数を使用して processNumbers を呼び出し、結果を保存する
// 必要な形式で結果を出力する
print('Number Processor');
print('================');
print('Original numbers: $numbers');
print('Operation: $operation');
print('Processing numbers...');
// TODO: ここで結果のリストをプリントする
print('Operation completed successfully');
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
論理とフローのすべてのレッスン
1リスト操作の応用
リストのプロパティ: first と lastリストの状態: isEmpty と isNotEmptyリストの反転リストへの追加: insertリストの削除: removeWhereリスト内の検索: indexOfリストのソートリストのシャッフルまとめ - リストオーガナイザー