パルカワ2

PerlとRubyとイチャラブ

Dart で簡単に data class を作りたい

Kotlinではdata classはこのように書ける。

data class User(val name: String, val age: Int)

これは、 ただのクラスではなくて equals() / hashCode() / toString() / copy() が実装されるクラスになる。 なので次のコードはtrueが返る。

User(name: "hisaichi5518", age: 1) == User(name: "hisaichi5518", age: 1) //=> true

Dartでこういうクラスを作ってみて、上記のような比較するとfalseが返ってしまう。

class Hoge {
  final String name;
  final Int age;
  Hoge({this.name, this.age})
}

これは equals が実装されていないからそうなる。つまりKotlinのようなdata classを作るには自前でequalsなどを実装する必要がある。 Dartリポジトリにもイシューとしてあがっている Add data classes · Issue #314 · dart-lang/language · GitHub

この問題を解決するライブラリは次のようなのがある。

これらのライブラリは, Dartのextensionを使わない方法で実装されている。 Dart 2.6から入ったextensionを使ったらもっとスマートな実装になるのでは?と思ったので調べてみたが、結論からいうと無理だった。

@immutable
class Hoge {
  final String name;
  final int age;
  Hoge({this.name, this.age});
}

// このextensionを自動生成してimportしてあげれば動くんじゃないかと考えた
extension HogeDataClass on Hoge {
  bool operator ==(Hoge other) {
    return other is Hoge && name == other.name && age == other.age;
  }

  ...
}

@immutableがついたクラスにextensionで ==toString() を実装すればいいと思ったのだけど、以下のような制限があると知った。

Extensions can’t declare members with the same name as a member declared by ‘Object’. Diagnostic messages | Dart

悲しい!