Hi 🙋‍♀️about me 😎posts 📚

TypeScript 開発者向け Dart におけるちょっと変わった構文集

intro

Dart は TypeScript を書いている人間ならば抵抗なく取り組むことができる言語だと思うが、たまに変な構文が出てくる。

今回は、先にここさえみておけば TS 開発者が Dart を触る上で構文上悩まなくて良くなると個人的に思っているモノをいくつか紹介しようと思う。

Cascade notation (..)

https://dart.dev/guides/language/language-tour#cascade-notation

これは対象となるオブジェクトに対し、プロパティ操作を連続して行うことができる構文だ。

querySelector('#confirm') // Get an object.
  ..text = 'Confirm' // Use its members.
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'));

↑ は ↓ と等価である。

var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));

みやすいかどうかは個人の見解による。

Named parameters

https://dart.dev/guides/language/language-tour#named-parameters

optional な引数を宣言したい場合に利用する。

void doDog({bool? isLargeDog, String? name}) {...}

name, isLargeDog はどちらも optional の引数となるので、呼び出し側では引数は不要になる。

doDog();

これの面白いところが、引数の順番に影響されない ところだ。

一見すると、order に影響を受けそうな感じがするが、下記のどちらも有効な呼び出しとなる。JS/TS で引数にオブジェクトを使った時の感覚に近い。

doDog(name: 'popop', isLargeDog: true);
doDog(isLargeDog: true, name: 'popop');

optional な引数を宣言したい場合と言ったが、必須パラメータの宣言も可能だ。

void doDog({required bool isLargeDog, String? name}) {...}

この場合、isLargeDog が必須パラメータとなる。

doDog(); // Error: Required named parameter 'isLargeDog' must be provided.
doDog(isLargeDog: true); // ok

Redirecting constructors

https://dart.dev/guides/language/language-tour#redirecting-constructors

class の construstor を複数用意できるような機能だ。

言葉で説明するよりも、code もみてもらったほうが早いと思う。

class Dog {
  String name;
  bool? isLargeDog;
  Dog({required this.name, this.isLargeDog = false});
  Dog.fromLarge({required String name}) : this(name: name, isLargeDog: true);
}

main(List<String> args) {
  final d1 = Dog(name: 'hoge');
  final d2 = Dog.fromLarge(name: 'fuga');
  print(d1.isLargeDog); // false
  print(d2.isLargeDog); // true
}

Dog.fromLarge が Redirecting constructors に該当する。

似ている機能で、Named constructors も存在している。

collection if & collection for

collection if

https://dart.dev/guides/language/language-tour#collection-operators

collestion 系の初期化時に、条件付きで値をセットすることができる。

main() {
  final isLargeDog = true;
  final List<String> list = ['Home', if (isLargeDog) 'Outlet'];
  print(list); // [Home, Outlet]
  final Set<String> sets = {'Home', if (!isLargeDog) 'Outlet'};
  print(sets); // {Home}
  final Map<String, bool> maps = {'Home': true, if (isLargeDog) 'Outlet': true};
  print(maps); // {Home: true, Outlet: true}
}

みやすいかどうかは個人の見解による。

collection for

https://dart.dev/guides/language/language-tour#collection-operators:~:text=Here%E2%80%99s%20an%20example%20of%20using%20collection%20for

collestion 系の初期化時に、loop 処理を記述することができる。

main() {
  var listOfInts = [1, 2, 3];
  var listOfStrings = ['#0', for (var i in listOfInts) '#$i'];
  print(listOfStrings); // [#0, #1, #2, #3]
}

みやすいかどうかは個人の見解による。

Symbol

単純に #symbol とするだけ。

  // true
  print(#bar == #bar);