I have the code
if (WORDLIST[language]==null) throw new Exception("Invalid Language");
List<String> wordlist = WORDLIST[language];
the compiler says
Error: A value of type ‘List?’ can’t be assigned to a variable of type ‘List’ because ‘List?’ is nullable and ‘List’ isn’t.
However its both not possible in my code for language to be set to a value that is not valid and just to be safe there is the exception thrown if it gets called somewhere without checking the language exists. How can I get the compiler to recognize this is valid?
Full Code is here(though the exception was added afterwards to try and handle new compiler):
https://github.com/mctrivia/bip39-multi/blob/mctrivia-patch-1/lib/src/bip39_multi_base.dart#L80
3
Answers
One way to hint to the compiler is to add an else clause, that way the compiler is sure the else branch will only execute when
WORDLIST[language]!=null
.Map.operator []
returns a nullable type, period. The compiler doesn’t know whatWORDLIST[language]
will return at runtime; it doesn’t know thatWORDLIST
isn’t someMap
implementation that returns different values each timeoperator []
is called. This is the same reason why only local variables can be type promoted.The typical ways to fix this are:
!
to force the result to be non-nullable:Since
wordlist
is probably already a local variable, you also could just reorder your code:The compiler is not smart enough to promote general expressions, only local variable can be promoted.
When you write
if (WORDLIST[language] == null) throw ...
, that doesn’t actually make the compiler any wiser wrt. the followingWORDLIST[language]
expression.It takes specific knowledge about the implementation of the
[]
operator ofWORDLIST
to guarantee that it returns the same value every time it’s called with the same argument. The compiler does not assume to have such knowledge.What you should do is:
By assigning the value to a local variable, you allow the test+throw to promote that variable to non-nullable in the following (implicit else-branch) code.