I'm playing with riverpod in flutter, and I got this example
AsyncError(:final error) => Text('Error: $error'),
It works, but I'm trying to understand what does :final error mean? If I remove the : it throws an error Object patterns can only use named fields.
Can you please provide a better example when is required to use it?
Trying to understand a certain syntax in Dart language
This is the ability to destructure a class instance field. To use the fields of an object at the time of destructuring, you can use the syntax Object(:[type] field) (conditionally). Here are more examples:
AsyncValue? value;
final result = switch (value) {
AsyncError(:final error) => '$error',
AsyncError(:var error, :StackTrace stackTrace) => '$error $stackTrace',
AsyncError(:var error, stackTrace: StackTrace st) => '$error $st',
AsyncError<int>(:final int value) => '$value',
AsyncError(:Object error) => '$error',
AsyncValue<int>(hasValue: true) => 'hasValue is true',
AsyncValue<int>(:var hasValue) when hasValue == false => '$hasValue',
_ => 'default',
The example itself doesn't make sense here, I only showed the syntax of field extraction. Specify : (or just inside the object's parentheses) and use the IDE prompts to see the fields available for destructuring.
Use a custom field when destructuring if necessary (as with stackTrace: StackTrace st).
You can also immediately start mapping fields to value, as in the AsyncValue.hasValue example. Use the when syntax if you need this field later.
There is a very large syntax, I recommend viewing the information using the links below:
TLDR: (:final error) is the pattern matching in Dart.
If you remove the colon :, Dart no longer recognizes it as pattern matching syntax and instead tries to interpret it as an object pattern.
: indicates the start of the pattern matching syntax.final error declares a variable error that will hold the error object contained within the AsyncError instance. The final keyword is used here to indicate that error will not be reassigned.When is required to use it?
if you want to make your code clean and expressive.
example: Handling a login State
abstract class LoginState {}
class Loading extends LoginState {}
class Success extends LoginState {
final String username;
Success(this.username);
}
class Error extends LoginState {
final String message;
Error(this.message);
}
now we can use it as:
Widget buildLoginWidget(LoginState state) {
return switch(state) {
Loading => CircularProgressIndicator(),
Success(:final username) => Text('Welcome, $username!'),
Error(:final message) => Text('Error: $message'),
};
}
from the example:
When you I write
Success(:final username) => Text('Welcome, $username!'), it means Im handling a state by matching theSuccesstype, extracting the object into a variable namedusername, and then using that variable to display a message in my UI with aTextwidget.
Im also just learn this things. Do not hesitate to correct me if im wrong.
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