🐱
Sound null safetyの扱い方
どのバージョンから?
Dart 2.12
何がnull safetyになる?
今まで通りに型を書くと自動でnon nullableになる。型?で書くとnullableになる。
例)
int a; //non nullable
int? b://nullable
nullの扱いはどう変わった?
今までは、nullはNull型で全ての型の派生型だったが、null safetyになってNull型は単純に独立したNull型になった(Object型の派生型でも無い)。今までのNull型に当たるのはNever型になった(全ての型&Nullの派生型)。
int?はどういう定義?
int?はint | Nullの共用型。これによりnullを代入できる。
intとint?の変換は?
nonnullableからnullableへはOK。逆はダメ。
int nonnullable = 1;
int? nullable;
//nonnullable = nullable;//これはダメ
nullable = nonnullable;//これはOK
int?からintへ変換できないの?
nullableの変数名に!を付けると変換できる。その代わりnullで無い事はプログラマーが保証しないといけない(nullだったら実行時エラー)。
int nonnullable = 1;
int? nullable;
nonnullable = nullable!;//nullableは実際にnullなので実行するとエラー
int?はnullチェックどうするの?
nullチェックしないでnullable変数を触ろうとすると構文エラーになる。nullチェックを入れれば触れる。
int? nullable;
//nullable.abs(); //nullチェック入れてないのでエラー
if文でチェックしているので.アクセスでOK
if(nullable != null){
print('nullable = ' + nullable.abs().toString());
}else{
print('nullable is null');
}
if文チェックでreturnしているので.アクセスでOK
if(nullable==null)return;
nullable.abs();
null-aware operatorsによるチェック
//?.でチェック
nullable?.abs();
//??でチェック
print('nullable = ' + (nullable ?? 1).abs().toString());
Neverを使ったチェック。
void throwException(){
throw Exception('Exception');
}
という例外を返す関数がある場合に
if(nullable==null)throwException();
nullable.abs();//エラー
だとnullable.abs()が実行される時はnullじゃない事が確実だが、構文解釈時には判断できずにエラーになる。その関数で処理が終わる(or例外で止まる)場合は、voidでは無くNeverを戻り値に指定するようにすると構文解釈時に判断出来てエラーでは無くなる。
Never throwException(){
throw Exception('Exception');
}
if(nullable==null)throwException();
nullable.abs();//OK
クラスのプロパティはif文のnullチェック効かないよ
class A{
int? val;
}
void main() {
A a = A();
if(a.val != null){
print('a.val.abs()=' + a.val.abs()); //nullチェックしているのにダメ
}
}
この場合は一旦ローカル変数に代入して、そのローカル変数をnullチェックして使う
int? nonnullable = a.val;
if(nonnullable != null){
print('a.val.abs()=' + nonnullable.abs().toString());
}
Discussion