📌

Dartでも戻り値を複数個返したい!

に公開

はじめに

関数やメソッドのコーディングをしていると

「戻り値を複数個返したい」

そんな時ってありませんか?

特にGo言語など、デフォルトでそれが出来る言語の経験があると、

「自分が今使っている言語でも出来たらなぁ〜」

だなんて思ってしまいます...

「戻り値をクラス型にすれば良いのでは...🤔」

とも思いますが、クラスに切り出す(抽象化する)程でもない時もありますよね...💦

Recordを使ってみよう!

そんな時、Dartには「Record」と言う便利なものがあります!

これは「複数の値を集約した不変の匿名型を表現するもの」なのですが、

これを使えば抽象化しなくても戻り値を複数個返せそうですよね!?

実際に簡単なサンプルを書いてみました。

(String, int) getUserInfo() {
  return ('Tanaka Taro', 6);
}

void main() {
  final (name, age) = getUserInfo();
  print('Name: $name, Age: $age');
}

上記のコードはgetUserInfo()と言う関数を実行すると

静的な値のまとまりを返し、print関数で出力するものです。

これでも良いのですが、

「戻り値の名前は特定のものにして、意味を持たせたい」

「より安全で保守性のあるものにしたい」

そういう時もありますよね...?

そんな時は...

({String name, int age}) getUserInfo() {
  return (name: 'Tanaka Taro', age: 6);
}

void main() {
  final person = getUserInfo();
  print('Name: ${person.name}, Age: ${person.age}');
}

このように名前付きフィールドを使うことで、

コードをより安全にすることもできます。

Future型でもやってみた!

もちろん、この書き方は非同期な型にも使えます!

Future<(String, int)> fetchUserData() async {
  // APIからデータを取得するシュミレーション
  await Future.delayed(Duration(seconds: 2));
  return ('Tanaka Taro', 6);
}

void main() async {
  print('Fetching user data...');
  final (name, age) = await fetchUserData();
  print('Name: $name, Age: $age');
}

または、名前付きフィールドを使うと...

Future<({String name, int age})> fetchUserData() async {
  // APIからデータを取得するシミュレーション
  await Future.delayed(Duration(seconds: 2));
  return (name: 'Tanaka Taro', age: 6);
}

void main() async {
  print('Fetching user data...');
  final person = await fetchUserData();
  print('Name: ${person.name}, Age: ${person.age}');
}

このように表現することもできます。

まとめ

今回はRecordを使うことで複数戻り値を返すコードを書いてみました。

「抽象化する程ではないけど、コードの可読性や保守性を上げたい」

そんな時に使えそうだと感じました😄

参考

Flutter実践開発

Dart 3 のRecord:複数の戻り値を効率的に扱う

Dart3のRecordについて

Discussion