Menu
CoddyTech

ジェネリックメソッド

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]
}

ジェネリックメソッドを使うと、メソッド単位で型安全性をきめ細かく制御でき、コンパイル時の型チェックの利点を活かしながら、クラスをよりシンプルに保てます。

challenge icon

チャレンジ

簡単

ジェネリックメソッドの力を示すデータ変換ユーティリティを作りましょう。クラス全体をジェネリックにすることなく柔軟に使える、あらゆる型に対応したメソッドを持つ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を使用する
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Dartオンラインコンパイラ