Open yukisakai1225 opened 5 days ago
From what you are saying, you want to be able to use when
also in subpatterns, right? Something like this?
var dummy = rnd.nextDouble();
x = switch(obj){
(Foo() || (Bar(b: var b) when b > 10) || (Baz(c: var c) when c == 0)) when dummy > 0.5 => ...
...
}
// aka having multiple when clauses in patterns, each one for it's own subpattern
If that's what you want, i believe the reason is because it makes it more difficult to read what is actually matching instead of just having one when
, where you can put all the additional checks. Another reason is that it makes patterns somewhat more difficult to compose, since one inner when
clause can alter the execution of the entire pattern.
There is one issue that has been talking about this (#4057), but only very briefly. It also proposes allowing functions in pattern, which would effectively be able to do the more complex subpattern checking, that you (probably) want.
I know this is what you are asking for, but sometimes you can rethink how you are going to express your code.
For instance, the above could be written as
final r = (0, 0);
final res = switch (r) {
(0, _) || (_, 1) => "A",
_ => "B",
};
Or
final (a, b) = (0, 0);
final res = switch(a) {
0 => "A",
_ when b == 1 => "A",
_ => "B",
};
Either way are more readable IMO, so you may want to use them, as currently it's impossible to do what you want with the syntax you want.
From what you are saying, you want to be able to use when also in subpatterns, right? Something like this?
You are right. Thank you for taking my intentions into consideration.
As you say, Separating the pattern and guard clauses would dramatically change the readability of the implementation regarding pattern matching.
@mateusfccp I want to separate a line for each value returned after the pattern match. So, this sentence is a little less than my favorite.
final (a, b) = (0, 0);
final res = switch(a) {
0 => "A",
_ when b == 1 => "A",
_ => "B",
};
I prefer the first example you presented.
final r = (0, 0);
final res = switch (r) {
(0, _) || (_, 1) => "A",
_ => "B",
};
If we want to add a guard clause to either (0, ) or (, 1), we need to separate the lines, as follow. I am looking for a way to avoid this.
final r = (0, 0);
final res = switch (r) {
(0, _) => "A",
(_, 1) when xxxx => "A",
_ => "B",
};
There's is the option of not using a switch expression, but a switch statement, where each body can have more than one case:
final r = (0, 0);
final String res;
switch (r) {
case (0, _):
case (_, 1) when xxxx:
res = "A";
case _:
res = "B";
}
It has only one line for each value signed to res
, and individual when
clauses for each pattern.
In the following code, “B” is assigned to res. This is because the guard clause is evaluated after pattern matching in line 3.
I expected the guard clause to affect each pattern as follows.
Consider other languages. In Swift, we can write guard clauses for each pattern, but in Rust and Scala, we cannot write guard clauses for each pattern. I would like to know the background behind this kind of specification for Dart.
I am not good at English, so sorry if my writing is not clear.