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

はじめに

Dart 3 からRecordが導入されました。Recordは構造化データを構築する方法を簡略化します。
色々使い道はあると思いますが、「複数の戻り値」を返すことができるようになったのが、一番の特徴かな、と思いますので、それを例に書いていこうと思います。

いままで、複数の戻り値を変えそうとしたら、新しいクラスを作るか、Mapを使う、Par,Tupleといったパッケージを導入する必要がありました。結果、型付きのないデータ構造を使うことで、型安全性が損なわれる。データを運ぶために新しいクラスを定義しなければならない、などで問題がありました。
しかしDart3では、それらが解決され、標準機能のRecordでできるようになりました!

Dartのバージョンを3以上に変更するのをお忘れなく!

書き方

Recordの基本形

(String, int) userInfo(Map<String, dynamic> json) {
  return (json['name'] as String, json['height'] as int);
}

final (String name, int height) = userInfo({'name': 'Michael', 'height': 180});
expect(name, 'Michael');
expect(height, 180);

final (name2, height2) = userInfo({'name': 'Michael', 'height': 180});
expect(name2, 'Michael');
expect(height2, 180);

複数の戻り値

(int x, int y) getNewPosition(int x, int y, int diff) {
    return (x + diff, y + diff);
}

final result = getNewPosition(3, 4, 5);
expect(result, (8, 9));
expect(result.$1, 8);
expect(result.$2, 9);

まとめ

Dart 3では、新機能としてRecordが導入されました。これは、構造化データの構築を簡単にし、開発者が複数の戻り値を効率的に扱えるようにします。以前は新しいクラスを作成したり、Mapを使用したり、パッケージを導入する必要がありましたが、Dart 3のRecordを使用すれば、これらの手間が省け、より型安全性を保った形でデータ構造を実装することが可能となりました。

この記事では、Recordの基本的な使用方法や、複数の戻り値を扱う際の具体的なコードスニペットを紹介しました。これにより、開発者はDart 3のこの新機能を活用し、コードの冗長性を減らし、型安全性を保つことができます。また、新たなバージョンのDartを活用するための準備として、Dartのバージョンを3以上に変更することを忘れないようにしましょう。これにより、Dart 3の強力な機能を最大限に活用することが可能となります。

参考

Dart 3を発表@Google I/O 2023

全ソース

import 'package:flutter_test/flutter_test.dart';

void main() {
  (int x, int y) getNewPosition(int x, int y, int diff) {
    return (x + diff, y + diff);
  }

  test('Recordの基本形', () {
    (String, int) userInfo(Map<String, dynamic> json) {
      return (json['name'] as String, json['height'] as int);
    }

    final (String name, int height) =
        userInfo({'name': 'Michael', 'height': 180});
    expect(name, 'Michael');
    expect(height, 180);

    final (name2, height2) = userInfo({'name': 'Michael', 'height': 180});
    expect(name2, 'Michael');
    expect(height2, 180);
  });

  test('複数の戻り値', () {
    final result = getNewPosition(3, 4, 5);

    expect(result, (8, 9));
    expect(result.$1, 8);
    expect(result.$2, 9);
  });
}