I have a class:
class Foo {
void bar() {}
}
And I'm using it like this:
Widget build() {
late Foo foo;
return Column(
children: [
ElevatedButton(
onPressed: foo.bar, // Error:
child: Text('Use'),
),
ElevatedButton(
onPressed: () => foo = Foo(), // Assigning foo here
child: Text('Initialize'),
),
],
);
}
The late local variable 'foo' is definitely unassigned at this point. (Documentation)
As you can see I'm using the late
keyword to give a hint to the analyzer that I'll be instantiating later, but I still see an error, why?
Note: I'm NOT looking for solutions on HOW to make it work but rather WHY it's not working?
Because you are creating the list right away as part of creating the Column
object for the children
argument. The list contains two ElevatedButton
objects which are also created right away as part of creating the list. For creating the first ElevatedButton
we provide two arguments, onPressed
and child
with values which are resolved and send to the ElevatedButton
constructor.
The problem is then that to resolve foo.bar
it needs get bar
from foo
. But foo
is late
and has definitely not been assigned any value at this point since no other code have been running which could provide a value for it.
Notice that when we provide arguments to methods/constructors the values we getting are resolved before we run code inside the method/constructor. Also, we are getting a copy of the reference, so foo.bar
needs to be resolved to some value since we cannot use this as some kind of pointer to the foo
variable inside build()
and later check if it is set to a value inside the ElevatedButton
object.