ジェネリックメソッド
CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 66/110。
クラスをジェネリックにできるのと同様に、個々のメソッドも独自の型パラメーターを持つことができます。これは、クラス全体をジェネリックにせずに、柔軟なメソッドが必要な場合に便利です。
ジェネリックメソッドでは、型パラメーターを戻り値の型の前に宣言します。
T findFirst<T>(List<T> items) {
return items.first;
}
void main() {
var firstNumber = findFirst<int>([1, 2, 3]);
var firstWord = findFirst<String>(['hello', 'world']);
print(firstNumber); // 1
print(firstWord); // hello
}Dartは引数から型を推論できることが多いため、常に明示的に指定する必要はありません。
var result = findFirst([10, 20, 30]); // Dart は int と推論するジェネリックメソッドは、型の柔軟性が必要なのが一部の操作だけであるクラス内で、特に役立ちます。
class Printer {
void printItem<T>(T item) {
print('Printing: $item');
}
List<T> duplicate<T>(T item, int count) {
return List.filled(count, item);
}
}
void main() {
var printer = Printer();
printer.printItem<String>('Hello');
printer.printItem(42); // 型はintと推論される
var copies = printer.duplicate('Hi', 3);
print(copies); // [Hi, Hi, Hi]
}ジェネリックメソッドを使うと、メソッド単位で型安全性をきめ細かく制御でき、コンパイル時の型チェックの利点を活かしながら、クラスをよりシンプルに保てます。
チャレンジ
簡単ジェネリックメソッドの力を示すデータ変換ユーティリティを作りましょう。クラス全体をジェネリックにすることなく柔軟に使える、あらゆる型に対応したメソッドを持つTransformerクラスを作成します。
コードを2つのファイルに分けます。
transformer.dart:次のジェネリックメソッドを持つTransformerクラスを作成します。T getFirst<T>(List<T> items)- リストの最初の要素を返しますT getLast<T>(List<T> items)- リストの最後の要素を返しますList<T> repeat<T>(T item, int times)- 指定された回数だけ項目を繰り返し含むリストを作成しますvoid printPair<A, B>(A first, B second)-Pair: [first] and [second]の形式で2つの値を出力します
main.dart:変換用のファイルをインポートし、異なる型を使って各ジェネリックメソッドの使い方を示します。Transformerのインスタンスを作成します[10, 20, 30]に対してgetFirstを使い、結果を出力します['apple', 'banana', 'cherry']に対してgetFirstを使い、結果を出力します[1.5, 2.5, 3.5]に対してgetLastを使い、結果を出力します'Hi'を4回繰り返すリストをrepeatで作成し、結果を出力します7を3回繰り返すリストをrepeatで作成し、結果を出力します'Name'と42を使ってprintPairを呼び出します100とtrueを使ってprintPairを呼び出します
各メソッドが独自の型パラメーターを宣言しているため、同じTransformerオブジェクトを整数、文字列、倍精度浮動小数点数、ブール値に対して使えることに注目してください。いずれの場合も、型安全性は完全に保たれます。printPairメソッドでは、1つのメソッドで2つの型パラメーターを使う方法を示しています。
期待される出力:
10
apple
3.5
[Hi, Hi, Hi, Hi]
[7, 7, 7]
Pair: Name and 42
Pair: 100 and true自分で試してみよう
import 'transformer.dart';
void main() {
// Transformerのインスタンスを作成する
var transformer = Transformer();
// TODO: [10, 20, 30]にgetFirstを使用し、結果を出力する
// TODO: ['apple', 'banana', 'cherry']にgetFirstを使用し、結果を出力する
// TODO: [1.5, 2.5, 3.5]にgetLastを使用し、結果を出力する
// TODO: repeatを使用して'Hi'を4回繰り返したリストを作成し、出力する
// TODO: repeatを使用して7を3回繰り返したリストを作成し、出力する
// TODO: 'Name'と42を指定してprintPairを使用する
// TODO: 100とtrueを指定してprintPairを使用する
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ自分で練習してみよう: Dartオンラインコンパイラ