Flutterで、下にベローンと表示される選択肢である「DropdownButton」というウィジェットがあります。
この「DropdownButton」内の選択肢が変更された際には、「onChanged」属性で設定したコールバック関数が呼ばれますが、
この「onChanged」属性のソースコードをみると、なんと「Null許容」を示す「?」が2つあって、「なんじゃこりゃぁ~!」という感じになっています。
「ValueChanged<T?>?」については
- ValueChanged? の部分と(1つめの「?」)
- <T?> の部分(2つめの「?」)
に分けて考えるとわかりやすくなります。
1つめの「?」(ValueChanged? の部分)は「ValueChangedがNullの可能性がある」
1つめの「?」(ValueChanged? の部分)は
ValueChangedがNullの可能性がある=onChanged属性がNullの可能性がある
という、Nullになる可能性があるものは型のうしろに「?」を つけるという、普通のNull許容の考え方と同じです。
2つめの「?」(<T?>)は「コールバック関数の引数がNullになる可能性がある」
一方、2つめの「?」の部分(<T?>)については、
onChanged属性のコールバック関数の引数がNullになる可能性がある
ことを意味しています。
つまり、ValueChangedはFunction(T value)であるため、その実態は引数が1つだけある関数を意味しており、Tは関数の引数の型として使われていることから、ValueChanged?の正しい理解は
- ValueChangedは引数を1つだけ持つ関数(Function(T value))であり
- 「T」はその関数に入れる引数(value)の型
- その「T」に「?」がついているということは、関数の引数(value)がNullになるかもしれない
ということになります。
(詳しくは、以下の動画で解説していますので、よろしければご覧下さい)