2023 - switch
with Dart 3.0 Pattern matching
Overview code
class Dog {
Dog({required this.name});
final String name;
}
class Cat {
Cat({required this.name});
final String name;
}
String checkType(dynamic v) {
String type;
switch (v) {
case Dog(:final name):
type = 'dog, $name';
case Cat cat:
type = 'cat, ${cat.name}';
case int:
type = 'int';
case (String name, String age):
type = 'Record ($name, $age)';
case {'user': {'name': final String name, 'age': final int age}}:
type = 'User Json $name, $age';
default:
type = 'unknown';
}
return type;
}
Object Destructing
switch (v) {
case Dog(name:final name):
// or You can skip name if use same name.
switch (v) {
case Dog(:final name):
⚠️ Docs: They are refuted if the value doesn’t have the same type.
You should use correct type to destructing object.
Just use final
or var
to indicate data type so you always use same type of object field.
return switch (v) {
Dog(:String age) => 'dog, $age', // Compile error 'The getter 'age' isn't defined for the type 'Dog'.'
Dog(name: String otherName) => 'dog, $otherName', // OK, Success to match
Dog(:int name) => 'dog, $name', // Fail to match
Dog(:String name) => 'dog, $name', // Success to match, But can't to be reached.
Just assign to variable (can be final with prefix final
)
case Cat cat:
type = 'cat, ${cat.name}';
or
case final Cat cat:
type = 'cat, ${cat.name}';
Record Destructing
case (String name, String age):
type = 'Record ($name, $age)';
Map Destructing
case {'user': {'name': final String name, 'age': final int age}}:
type = 'User Json $name, $age';
You can also use switch
expression.
String checkType(dynamic v) {
return switch (v) {
Dog(:final name) => 'dog, $name',
Cat cat => 'cat, ${cat.name}',
int => 'int',
(String name, String age) => 'Record ($name, $age)',
{'user': {'name': final String name, 'age': final int age}} =>
'User Json $name, $age',
_ => 'unknown',
};
}
You can check more information in the Dart docs
map
to handle all cases ormaybeMap()
to only handle the case you need. – Chemarin