Dartで引数への再代入を制限する方法
はじめに
関数の引数の再代入を許容してしまうと、コードを読む際に引数の値が変わっていることがあり余計な脳のメモリを使うことになるのでコードが読みにくくなるし、それによってバグの可能性も生んでしまう。
本来は言語仕様として引数への再代入は制限しておいてほしいがDart言語はそうではない。
今回は引数への再代入の制限方法を2パターン紹介する。
方法
引数にfinal
をつけて制限する
一般的な方法は引数にfinal
をつけることだろう。明示的にfinal
を指定しているので再代入されることがないと分かりやすい。
hoge(final String text) {
text = 'fuga';
}
// Error: Can't assign to the final variable 'text'.
リントのルールで制限する
一方で、上記の方法では引数の数が多くなったときにfinal
だらけで行の長さが大きくなってしまう(そもそもそんな関数を作らないようにしようという議論は割愛)。
そこでparameter_assignments
というリントのルールを有効にすることで、final
をつけずとも引数への再代入を制限することもできる。
ちなみにこのルールでは、nullableな引数に対して??=
演算子を使うことで値の代入が許されるようだ。
// これは許される
hoge(int required, {int? optional}) {
optional ??= 1;
}
// これも許される
fuga(int required, [int? optional]) {
optional ??= 1;
}
また、このルールをつけることで引数にfinal
がついているものとそうでないものが混在することを防ぐためにavoid_final_parameters
のルールも有効化しておくことをおすすめする。
一方で、このリントルールによる方法では引数の再代入が制限されていると知っておくためには、プロジェクトのリントルールを把握しておく必要がある。
おわり
明示的にfinal
をつけて制限するか、final
を省略してリントルールによって制限するかどうかは、チームで話し合って決めるべきだろう。
個人的には「引数に再代入できるとコードが読みにくいよね」という認識がチームで共有できているのであれば、リントルールで良さそうだと思っている。