46
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

FlutterAdvent Calendar 2022

Day 25

Dart 3 でやってくるRecord型の紹介

Last updated at Posted at 2022-12-24

どうも、SupabaseでDevRelをしているタイラーです!

12月9日にFlutter公式Twitterアカウントより2023年の中頃までにDart 3がリリースされ、Flutterもそれに移行することが発表されましたね。

今回はそんなDart 3で新しくレコード型という型が追加されるのですが、これが便利なので紹介させてください。

*ここで書いていることはまだ開発中の機能もあるのでもしかしたら変更になることもあるかもしれません。あくまで「こんな雰囲気の機能がやってくるんだ」くらいの感じで読んでいただけたら幸いです。

Record型の基礎

Dartでは今まで複雑な型を持つデータを定義する際にいちいちクラスを定義しなくてはならなかったのですが、このレコード(Record)型の登場で毎回クラスを定義する必要がなくなり、TypeScriptなど他の言語に近い感覚で開発をすることができるようになりました。また、他の言語で目にするTuple的な使い方もできるようになっています。

レコードは()を使って書き、また引数の定義の仕方と同じで{}でプロパティを囲うことでそのパラメーターをnamed parameterにすることができます。

// Positional argumentのみを使った例
(int myNumber, String myName) data = (1, 'Jon');
final myNumber = data.$0; // Positional argumentは`$[index]`の書き方でアクセスする
final myName = data.$1;

// Positional argumentとnamed parameterを混ぜた例
(int myNumber, {String myName}) data = (1, myName: 'Jon');
final myNumber = data.$0;
final myName = data.myName; // Named parameterは普通にそのパラメーター名でアクセスできる

実例

これを使うとコードをスッキリ書くことができるシチュエーションがあったりします。
例えば、パジネーション機能を実装するときにロードしたデータ、現在のページ、総ページ数の三つの値をAPIから引っ張ってきて返すような関数があったとしましょう。Dart 2ではこんな感じで書けると思います。

class PaginatedData {
  final List<Item> items;
  final int currentPage;
  final int totalPages;

  PaginatedData({
    required this.items,
    required this.currentPage,
    required this.totalPages,
  });
}

Future<PaginatedData> getPaginatedData(int currentPage) async {
  // APIリクエストを投げるなどしてデータを引っ張ってくる

  return PaginatedData(
    items: items,
    currentPage: currentPage,
    totalPages: totalPages,
  );
}

ここの例で言うPaginatedDataは特にクラスとして意味はなくただ単に3つの値をいっぺんに返すためだけに作られたクラスです。Dartで開発をしているとこのように複数の値を返すためだけのクラスが増えがちです。しかし、新しくできたレコード型を使うとこんな風にスッキリ書くことができます。

Future<({ List<Item> items, int currentPage, int totalPages })>
 getPaginatedData(int currentPage) async {
  // APIリクエストを投げるなどしてデータを引っ張ってくる

  return (
    items: items,
    currentPage: currentPage,
    totalPages: totalPages,
  );
}

余計なクラスがなくなりだいぶコードがスッキリした感じがありますね。値は一度関数の戻り値を変数に受け取り、それのプロパティにアクセスすることできます。

final data = await getPaginatedData(currentPage);
final items = data.items;
final currentPage = data.currentPage;
final totalPages = data.totalPages;

これも悪くはないのですが、実はDestructuringという機能を使い一発でこれら三つの変数を取り出すこともできます。

final (:items, :currentPage, :totalPages) = await getPaginatedData(currentPage);

この一行だけでitems, currentPage, totalPagesという変数が作られ、それぞれ値が入ってくる形になります。

全体的に使い勝手はTypeScriptのオブジェクトとだいぶ類似していますね。昨今はBackendの構築でTypescriptを触っている人も多いかと思うのでだいぶこのアップデートは嬉しいのではないでしょうか!

レコード型の詳しい仕様はこちらに書いてあるので興味がある方は見てみてください。

また、DartのDevチャンネルではすでにDart 3を試すことができますので気になる方は触ってみてください!

46
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
46
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?