torikatsu.dev

Flutterとかプログラミングとかガジェットとか書きます

null-safetyとお友達になるTips

こんにちは、とりかつ((@torikatsu923)https://twitter.com/torikatsu923)です。

Flutterで開発をする際はDartを書くことになります。DartにはNNBD(null-safety) があり、Flutter側でもnull-safetyの対応がどんどん進んでいます。 null-safetyのおかげで、nullが入りこむことによって起こるバグを見つけやすくなりました。 私もFlutterの開発をする際はnull-safetyをonにしているのですが、このnull-safetyの恩恵にあやかるためにはちょっとした工夫が必要になります。 今回の記事では、そんなnull-safetyと最高のお友達になるためのtipsを2つ紹介します。

note 今回の記事は以下のdocsの更新を受けてのものです。 一時ソースをサクッと確認したい方は以下からお願いします。 dart.dev

nullチェックしてるのにnullの可能性があるとコンパイラに怒られるケース

Dartのコードを書いていると、以下のようにnullチェックをすることがあると思います。

一見正しそうに見えますが、実際にやってみるとコンパイルエラーになります。 f:id:torikatsu923:20210619164656p:plain

エラーの内容は以下の通りです。

The method 'toDouble' can't be unconditionally invoked because the receiver can be 'null'.
Try making the call conditional (using '?.') or adding a null check to the target ('!').dart(unchecked_use_of_nullable_value)

ざっくり訳すと「valueはnullの可能性があるからtoDoubleは呼び出せないよー」となります。 手前でnullチェックをしているのにvalueがnullの可能性があるとはどういうことでしょうか、、、

Tips1 ローカル変数に切り出す

実はこれ、一度ローカル変数に切り出すことでうまく切り抜けることができます。 試しに以下のようにfinal v = value;のようにしてみます。

すると、、、

f:id:torikatsu923:20210619165402p:plain エラーが消えました!!🎉🎉

Tips2 !を使って握り潰す

どこからどうみてもnullでない値なのにnullの可能性があるなんて言われた時には!(bang operator)を使用することもできます。 以下のようにコードを変更してみると、、、

f:id:torikatsu923:20210619171016p:plain

エラーが消えました!!🎉🎉

実はこの方法、一つ注意することがあります。 MyIntegerのコードの例ではvaluefinalのため変更されることがないので問題が起きません。 しかし、valuefinal出ない時は7行目でnullチェックをした後に値が書き換えられる可能性があります。 もし値が書き換えられてnullが入り込んでしまうとクラッシュしてしまいます。 bang operatorは簡潔に記述することができますが、使い方によっては思わぬバグを作り込む原因になってしまうため、使用する際には十分に注意を払う必要があります。

個人的には少し冗長ですが1の方法が安心感があって好みです。

終わりに

今回はnull-safetyとお友達になるTipsを2つ紹介しました。 Kotlinとか触ってからdartを触るとなんでnullableと判定されちゃうん、、、というケースがちょくちょくあって初めはびっくりしました。 しかし、ちゃんと付き合い方を知れば心強い味方になってくれます!

それでは良い開発ライフを!