事象について
flutterで以下のようなソースコードで
Non-nullable instance field ‘変数’ must be initialized
というエラーがでる場合
class _MyHomePageState extends State {
String _test; //←ここでエラー
@override
void initState() {
_test= "";
super.initState();
}
(省略)
}
3パターンの解決方法があります。
- lateを宣言する
- 初期値にnull以外をセットする
- 修飾子『?』をつける
1つずつ解説していきます
解決方法
1、lateを宣言する
class _MyHomePageState extends State {
late String _test; //←lateを追加
@override
void initState() {
_test= "";
super.initState();
}
(省略)
}
2、初期値にnull以外をセットする
class _MyHomePageState extends State {
String _test = ""; //←初期値にnull以外をセット
@override
void initState() {
_test= "";
super.initState();
}
(省略)
}
3、修飾子『?』をつける
class _MyHomePageState extends State {
String? _test; //←修飾子『?』をつける
@override
void initState() {
_test= "";
super.initState();
}
(省略)
}
原因(ザックリ解説)
Flutter2のバージョンが上がり
という文法が有効になったためです。
ざっくりいうと
Nullを容易に変数にセットできない仕様になりました。
そのため
それに応じた実装をしなければならなくなりました。
- 特別な修飾子(?・!・late・required)
- IF文でのNullチェック
- 演算子 ??でのNullチェック
- 定義時にNull以外の値をセットしておく
などなど・・・
今回の例は
- 修飾子「?」「late」をつける。
- 定義時にNull以外の値をセットしておく
などの方法で回避できます。
修飾子「?」 の意味は?
修飾子『?』の意味は
Nullを許可する
という意味です。
上記の説明の通り「Null Safety」により、
Nullを変数に入れるのは原則禁止になりました。
しかし、修飾子『?』をつけることによってその変数に関してはNullをセットすることを許可しています。
『修飾子『?』をつける』の例をもう一度みてます。
修飾子『?』をつける
class _MyHomePageState extends State {
String? _test; //←修飾子『?』をつける
@override
void initState() {
_test= "";
super.initState();
}
(省略)
}
この例では3行目、宣言時に変数に何も設定されていませんね。
何も入っていないということは、言い換えるとNullが入っている状態ということです。
つまり『Null Safety』の原則に反しているわけです。
なので、今回のエラーが発生します。
修飾子『?』をつけるとNullを許可するようになるので、エラーが解消されるわけです。
修飾子『late』の意味は
修飾子『late』の意味はザックリいうと
Null以外の値を後で設定すること
を宣言しています。
修飾子『late』をつけるソースコードの例をもう一度みてます。
class _MyHomePageState extends State {
late String _test; //←lateを追加
@override
void initState() {
_test= "";
super.initState();
}
(省略)
}
『Null Safety』の導入により、変数を宣言した場合、初期値はNullなのでエラーとなりますがlateを宣言することで、一旦回避できます。
宣言時には初期値はセットしておく必要はなく、必ず後で初期値以外の値を設定する場合に使います。
上記の例も『_MyHomePageState』が呼び出されるたびに必ずinitState()が呼ばれるようになっていて、そこに『_test= “”;』しています、
つまり、必ずnull以外がセットされるソースコードになっていますよね。
ご存じの通り「late」は日本語で「後で」という意味です。
Null safetyという文法に対して、
Nullは『後で』設定するからエラーを表示しなくて良いですよ
と伝えているのが修飾子「late」だと思えば覚えやすいかもしれません。
Flutterあるある
公式サイトやブログのサンプルコピペしただけなのにエラーが出た!
っていう事象は大体この「Null safety」が悪さをしていることが多いです。
2021年5月20日以降から 「Dart 2.13」になり、「Null safety」が必ず効くようになったので、
それ以降のサンプルプログラムは動かない可能性があると思った方が良いです。
書籍購入の際も注意
そもそもFlutterは文法が変わってくと思われるので書籍を購入することはお勧めしません。
もし、購入するのであれば、新しいものを購入した方が良いです。
巻末の版数をみて2021年6月以降のものを対象に購入を検討することをお勧めします。
ちなみに以下の書籍は初版が2021年8月24日でNull Safetyに関する説明がありました。
(2ページ程度だけですが、スッキリまとまっていると思います。)