Why does Dart allow this:
void main() {
var A;
A ??= 12;
print(A);
}
The output is 12. But not this:
void main() {
int A;
A ??= 12;
print(A);
}
Here's the error:
lib/project_dart.dart:4:2: Warning: Operand of null-aware operation '??=' has type 'int' which excludes null.
A??= 12;
^
lib/project_dart.dart:4:2: Error: Non-nullable variable 'A' must be assigned before it can be used.
A??= 12;
^
lib/project_dart.dart:5:8: Error: Non-nullable variable 'A' must be assigned before it can be used.
print(A);
^
In this case I have to add the ?
after int
so it can work but in the previous case it works fine without it the question is WHY?
var
tells the compiler "I want you to figure out what type this variable should be" based on the assignment. In this case, there is no assignment to the variable upon declaration, so there is no information for the compiler to use to infer the type. Thus, according to the compiler, the type of A
should be dynamic
, which could be literally anything, so it's given the default value of null.
int
explicitly tells the compiler "I want this variable to be a non-nullable int". Non-nullable variables cannot be given a default value when they are declared without a value, so they must be assigned before they are referenced for the first time, which means you can't do print(A)
before A
has been definitely given a value.
A ??= 5;
is less obvious why it's failing, but think about what it's doing. It checks if A
is null, and if it isn't, it assigns it the value of 5. In order to check A
, the program needs to reference A
, and as we know, A
can't be referenced because it's not nullable and hasn't been definitely assigned a value. Additionally, A ??= 5
is redundant because A
is non-nullable and therefore can never be null.
Note that a declared variable that hasn't been assigned a value is not going to implicitly contain null. There is no check for whether a variable has been assigned yet, which is why you should be careful when declaring non-nullable variables without immediately assigning them a value. It's easy to find yourself in a race condition where code that will assign the variable may or may not occur before other code that will reference the variable.