Given the following function:
(String, int)? getPair() {
return ('hello', 42);
}
I can access the multiple returns using the fields like so:
final pair = getPair();
if (pair != null) {
String word = pair.$1;
int number = pair.$2;
}
However, I'd prefer to destructure the values using some sort of pattern matching. This is what I tried:
final (word, number) = getPair();
But that gives the following error:
The matched value of type '(String, int)?' isn't assignable to the required type '(Object?, Object?)'. Try changing the required type of the pattern, or the matched value type.
How would I change the required type of the pattern or the matched value?
Related reference:
You can do that destructuring after the null
-check, like you did manually using $1
and $2
:
final pair = getPair();
if (pair != null) {
final (word, number) = pair;
// ...
}
You can do a not-null
assert as part of a declaration pattern:
final ((word, number)!) = getPair();
That will throw if the value is null
.
You cannot do a null
check as part of a declaration, because declaration patterns must be irrefutable, and a check can fail.
You can do the null check as part of a refutable pattern check, using ?
:
if (getPair() case (final word, final number)?) {
// ...
} // else { "or else, if needed"; }
or
switch (getPair()) {
case (final word, final number)?: // ....
// default: "or else, if needed";
}
Since you're then also matching the type in the following destructuring, the ?
can be removed.
Or you can combine the two approaches, if you also want the binding of pair
:
if (getPair() case final pair?) { // Bind `pair` if it's not `null`.
final (word, number) = pair;
}