In Dart, one can use switch statements rather than a long if-then-else
var command = 'OPEN';
switch (command) {
case 'CLOSED':
executeClosed();
break;
case 'OPEN':
executeOpen();
break;
default:
executeUnknown();
}
but sometimes we just want to provide a value based on a condition. Like, inside of an function call, class instantiation, or setting the value of a variable, etc.
For example
// Doesn't work, but wish it did
MakeNametag(
adjustFontSize: switch(status) {
case 'young' : return 'large';
case 'old' : return 'largest';
default: return 'normal';
} //end switch
}
);
If you just have two options, one can use conditional operator (sometimes called ternary operator)
// Works
MakeNametag(
adjustFontSize: ['old','young'].contains(status) ? 'larger' : 'normal');
(javascript has the same operator and issue)
CodePudding user response:
In Dart, switch
is only a statement, not an expression, so you can't use it as an argument, which must be an expression, and have a value.
What you can do is to either define a helper function:
String fontSizeFromAge(String age) {
switch (age) {
case 'young' : return 'large';
case 'old' : return 'largest';
default: return 'normal';
}
}
MakeNametag(
adjustFontSize: nameTagFromAge(status)
);
or, if you insist on having the switch where the value is used, you can write and call the function at that point:
MakeNametag(
adjustFontSize: () {
switch (status) {
case 'young' : return 'large';
case 'old' : return 'largest';
default: return 'normal';
}(),
);
The (){ ... }()
syntax is a zero-parameter function literal () { ... }
that is immediately called with zero arguments, ... ()
. That's the only real way to put statements into expressions in Dart.
CodePudding user response:
Often times instead of a simple switch statement, you can define a map literal and immediately subscript []
into it. Use the if null operator ??
for the default
case.
MakeNametag(adjustFont: {'young': 'large', 'old': 'largest'}[status] ?? 'normal');
Often times you can also make the map literal const
for a small performance improvement.
MakeNametag(adjustFont: const {'young': 'large', 'old': 'largest'}[status] ?? 'normal');
CodePudding user response:
Yes. I found it while playing around with syntax, and I think the following looks better than most other ways. One can chain the ternary operator.
The following is an example of using the "switch" idea within a parameter passed to a function:
void main() {
int a=2;
print(
a==1 ? "s" :
a==2 ? "t" :
a==3 ? 'u' :
a==4 ? 'v' :
a==5 ? 'w' :
'x'
);
}
This is what the above example would look like using the example in the question.
MakeNametag(
adjustFont:
status=='young' ? 'large' :
status=='old' ? 'largest' :
status=='funky' ? 'wavy' :
status=='microsoft' ? 'timesNewRoman' :
status=='google' ? 'roboto' :
'normal',
}
);
There are many others ways to do this, like creating a class or using a Map
object and looking up the value based on a key. But this is the most compact way I know of.
PS. I wrote this up because I found it hard to find the answer of what to call this pattern.