void main() {
myCar mebicar = myCar(parts: tyre);
mebicar.parts();
}
class myCar {
myCar({this.parts});
final Function? parts;
}
void tyre() {
print("black tyre");
}
CodePudding user response:
Since you have a question mark '?' in final Function? parts;
, this method can be null
. It is not possible to call a null function. You can fix your code with a check before calling the method:
myCar mebicar = myCar(parts: tyre);
if(mebicar.parts != null){
mebicar.parts();
}
CodePudding user response:
The error comes from Dart's ability to protect you from potentially nullpointer exceptions. This is done by having the concept of differentiate between nullable and non-nullable types. And when dealing with nullable types, we are enforced by Dart to either handle the case of the value being null, or tell Dart that you know the risk but it is fine.
In your case, you have defined the parts
variable to be a nullable type Function?
(the question mark tells us it is nullable). So the variable can point to a Function
or null
.
Dart will then warn us about the risk of the field being potentially null
in case we try use the field without ensuring it is safe to use it. There are several ways we can solve this.
We could change the type to Function
by requiring a value for the variable when creating the myCar
object:
class myCar {
myCar({required this.parts});
final Function parts;
}
If we don't want to do any changes to myCar
we can either solve it by creating a local variable where we checks for null
. This check will end up doing a automatic type promotion of the partsFunction
variable:
void main() {
myCar mebicar = myCar(parts: tyre);
Function? partsFunction = mebicar.parts;
if (partsFunction != null) {
partsFunction();
}
}
Alternative we can do this:
void main() {
myCar mebicar = myCar(parts: tyre);
if (mebicar.parts != null) {
mebicar.parts!();
}
}
Of if you are sure the variable are never null
you can also just do:
void main() {
myCar mebicar = myCar(parts: tyre);
mebicar.parts!();
}
The point of !
is to tell the Dart compiler that it should just ignore this potential nullpointer exception and instead insert a runtime check which will be checked when running your application. So in case of mebicar.parts
being null
at runtime, the application would crash.
The reason why if (mebicar.parts != null)
does not trigger a automatic type-promotion is that we in Dart have the concept of getter/setter methods that should be able to act as if they are normal variables in a class. So in Dart, we cannot differentiate between a class variable and a class getter/setter.
Since getter/setter are normal methods, they are allowed to return a different result each time they are called. So that means that just because we did a type check with if (mebicar.parts != null)
, it doesn't mean that the second time we ask for mebicar.parts
, that the value are not null
.
This is why we can do the type promotion of saving the value into a local variable since we here know for sure that the variable keeps it value between readings as long we have not done any writing to it between the readings.