![見出し画像](https://assets.st-note.com/production/uploads/images/49676207/rectangle_large_type_2_785ee42096985394c34ffcd43e0bece8.png?width=800)
DartのNullSafetyについて確認してみる2
前回に続き、DartのNullSafety対応について、何が出来るようになったのかを確認してみる。
Working with nullable types
Null-aware operator
NullSafety対応前から使える Null-aware operator `?.` がよりスマートになったらしい。
NullSafety対応前に以下のようなコードを書くと、引数に null が入ってきた場合はエラーとなってしまう。message?.trim() の評価結果が null になる場合もあるので特におかしいわけではない。
String hoge(String message) {
return message?.trim().toUpperCase();
}
で、エラーを回避するためにはこうする必要がある。
String hoge(String message) {
return message?.trim()?.toUpperCase();
}
しかし、NullSafety対応後は以下のようなコードを書いてもエラーとはならなくなっている。
String? hoge(String? message) {
return message?.trim().toUpperCase();
}
これは、message?.trim() の評価結果が変わったのではなく、Null-aware operatorを使ったメソッドチェーンでは、nullと評価された後の処理をスキップする、という仕組みになっているらしい。
Null-assertion operator
他の言語でもよくある `!` を Null-assertion operator と呼ぶらしい。強制的に non-nullable として扱うためのもの。
Late variables
`late` を付けて変数を宣言すると、コンパイル時ではなく実行時に制約を強制する事が出来る。
final で宣言したいけど、値が入るタイミングはインスタンスが生成された後、みたいな時に使えるはず。lateを付けた変数に初期化せずにアクセスしたり、この場合だとfinalなのに複数回初期化しようとするとエラーとなる。
class User {
late final String firstName;
late final String lastName;
void setFullName(String first, String last) {
firstName = first;
lastName = last;
}
String getFullName() {
return firstName + ' ' + lastName;
}
}
Required named parameters
metaパッケージに入っていた @required に相当するものが、使えるようになった。コンパイル時にミスを検知できるようになるので、一括して置換しておくと良いかもしれない。
void hello({ required String message }) {
print(message);
}
Abstract fields
NullSafety対応後に以下のようなコードを書くとエラーとなるらしい。
abstract class Hoge {
String name;
}
で、getter と setter をそれぞれ定義すればOKらしいが面倒くさいので、abstract を付けて変数を宣言できるようになったらしい。
abstract class Hoge {
abstract String name;
}
Nullability and generics
ジェネリクスにおいても ? を付けることで nullable であることを表現できる。
以下のようなコードを書いた時に、object に null が入っている時は object as T としても null になるらしい。
class Box<T> {
T? object;
Box.empty();
Box.full(this.object);
T unbox() => object as T;
}
Core library changes
The Map index operator is nullable
Mapの値を参照する時は、キーが存在するか分からないので必ず nullable になる。なので、NullSafety対応後はそれを考慮して、Null-assertion operator を付けるなりする必要がある。
var map = {'key': 'value'};
print(map['key']!.length);
No unnamed List constructor
List のデフォルトコンストラクタ List() がなくなったらしい。もし使ってたら [] とかに置き換えればとりあえずOKそう。
Cannot access Iterator.current before or after iteration
iterator.current が null を返すようになったので E ではなく E? になると。これも使っていたら適宜対応すればOKそう。
最後に
やはり、地味ではあるが理解しておくとより安全なコードを、より理解しやすい形で書けるようになる気がする。
この記事が気に入ったらサポートをしてみませんか?