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
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);