I declared a callback method inside a Stateful class like:
final void Function(int index)? onSelected;
MyBottomNavigationBar({@required this.onSelected});
and called using widget.onselected inside state class like:
widget.onSelected!(_selectedIndex);
But I'am not able to understand the actual use of ! Bang operator. I can't initialize widget.onSelected in constructor without giving ? during declaration.
My main question is "How ! bang operator is handling the null values? What's the use of it ?
The Bang
operator does nothing more than tell Dart
that even if we have defined some variable as a Nullable
type, it will definitely
not be null.
Dart's Nullable safety
and Flow Analysis
are here to make the developer's life easy by avoiding runtime error and catching them at compile-time itself.
When you define,
final void Function(int index)? onSelected;
You are telling dart that this variable may or may not
be assigned a value and thus it may or may not be null
.
Now, whenever you try to use it like this,
widget.onSelected()
Dart will warn you that, this is a Nullable
typed variable hence take extra care.
If Dart didn't tell you this before hand, then you would've realized it after you ran the app and it crashed while trying to call the function.
Now, since Dart has warned you that you cannot use it like that, there are two ways to approach it.
Put a null check before using it. This way we are avoiding runtime errors.
var onSelected = widget.onSelected;
if (onSelected != null) onSelected(_selectedIndex);
This creation of a new local variable is necessary since Dart's flow analysis only works on local variable null checks and not class level variable null checks.
Use the bang
operator,
widget.onSelected!(_selectedIndex)
Now the issue with this is that, you are just assuring Dart that it will never be null, but if it were actually null, it will still result in a runtime crash.
So, the Bang
operator is just a way to bypass Dart's flow analysis
when you have to access a nullable typed variable.
Hope this clears at least a bit of your doubt.
The bang operator works like an assert
statement but in production mode too.
Let's say, this is your function.
final void Function()? foo;
You can't call it directly
foo(); // Error
Here comes a bang operator, which actually says that Dart I take the full responsibility that this function isn't null
, let me proceed with the call.
foo!(); // No error
This is essentially equal to doing:
(foo as Function())();
Note:
You will run into an error if foo
was null
. A good approach is to check for nullability using a local variable and proceed to the call.
final f = foo;
if (f != null) {
f();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With