🔷
Dartの?? ??= ?. …?演算子(Null-aware演算子 / null-aware operators)について
はじめに
- はてな2つの演算子『??』とか、はてな+ドットの演算子『?.』とかややこしいのでまとめてみました。
- Dartでは『nullの可能性があるものを扱う時に便利な演算子』がある。それがこの子達。
??
- ??演算子(null演算子)と呼ばれる。
- Dartにおいて、
??
は「if null」を意味する。 - ??演算子の左側の式が
null
でなければ、その値を返す。左側の式がnull
なら、右側の式の値を返す。
void main() {
print(1 ?? 3); // <-- 1
print(null ?? 12); // <-- 12
print(0 ?? 1); // <-- 0
print(null ?? null ?? 30); // <-- 30
}
??=
- ??=演算子。英語ではnull-aware assignment operator
- 変数の現在の値が
null
の時は代入を行う。変数の現在の値がnull
でない時は代入が行われない。
void main() {
int? num; // <-- 初期化してないのでnumはnull
print(num); // <-- null
num ??= 5;
print(num); // <-- 5
num ??= 100; // <-- numの値はnullではないので、100の代入は行われない。
print(num); // <-- 5
}
?.
- ?.演算子。英語ではnull-aware access(method invocation) operator
- ?.演算子は、
null
かもしれないオブジェクトの『プロパティ』や『メソッド』にアクセスしようとしてアプリがクラッシュするのを防ぐ。 - オブジェクトが
null
の場合、null
が返ってくる。下の例で言うと、value
がnull
なので?.演算子を使用して書くとnull
が返ってくる。 - チェーンしてワンライナーで書くこともできる。
void main() {
String? value; // <-- 初期化してないのでvalueはnull
print(value.toLowerCase()); // <-- ?.演算子を使用せず、かつvalueがnullのためエラー
print(value?.toLowerCase()); // <-- オブジェクト(value)がnullなのでnull
print(value?.toLowerCase().toUpperCase()); // <-- toLowerCase()の後ろで?.演算子を使用せず、かつvalueがnullのためエラー
print(value?.toLowerCase()?.toUpperCase()); // <-- オブジェクト(value)がnullなのでnull(チェーンしてワンライナーで記述)
print((value != null) ? value.toLowerCase() : null); // 2つ目のprint文はこのコードと等価。
}
class HogeObject{
int? num;
HogeObject({this.num});
}
void main(){
var hogeObject = null;
print("${hogeObject?.num?.toString()}"); // <-- null
print("${hogeObject?.num}"); // <-- null
HogeObject hogeObject_1 = HogeObject();
print("${hogeObject_1?.num?.toString()}"); // <-- null
print("${hogeObject_1?.num}"); // <-- null
HogeObject hogeObject_2 = HogeObject(num: 50);
print("${hogeObject_2?.num?.toString()}"); // <-- 50
print("${hogeObject_2?.num}"); // <-- 50
}
- ?.演算子を使わずに書くと以下のように
null
でないことをいちいちif文でチェックすることになる。これを避けるため上記のように?.演算子を使用する。
void main() {
String? input;
if (input != null) {
print(input.length);
print(input.toLowerCase());
}
}
…?
- 英語ではnull-aware spread operator
- 日本語を使用して表現すると『null-awareスプレッド演算子』か。
- スプレッド演算子を使用する際、
null
要素を追加することを防ぐ。
void main() {
Map? map_1 = {1: 'マンゴー', 2: 'リンゴ'};
Map? map_2 = {3: 'みかん', 4: 'メロン'};
Map? map_3 = null;
var mergeMap = {...?map_1, ...?map_2, ...?map_3}; // null-awareスプレッド演算子を使用してマージする
print(mergeMap); // <-- {1: マンゴー, 2: リンゴ, 3: みかん, 4: メロン}
List<int> numList = [1, 2, 3];
List<String>? stringList; // <-- 初期化してないのでstringListはnull
print(['おはよう', ...stringList]); // <-- エラー
print(['おはよう', ...?stringList]); // <-- [おはよう]
print([0, ...?stringList, ...numList]); // <-- [0, 1, 2, 3]
}
(最後にソッといいねボタンやバッジを贈るボタンを押して頂けたら幸いですm(_ _)m)
参照
Discussion
?
の右にあるコレクションのnull
要素は展開されます。?
の右にあるnull
可コレクション変数がnull
の場合にその展開をスキップします。