-
Notifications
You must be signed in to change notification settings - Fork 214
Could a constant map that has a non-infinite type as key know that it is exhaustively defined? #1717
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I had a similar idea a couple of minutes ago and I was going to open a similar issue when I found yours. My idea was to extend it to all constant values. For example, in the snippet below, I think that the compiler, given that const Map<int, String> romans = {1: "I", 5: "V", 10: "X", 50: "L"};
print(romans[1].toLowerCase());
// Raises Error: Method 'toLowerCase' cannot be called on 'String?' because it is potentially null. Maybe this makes more sense with enums, but it's just my two cents. |
@enzo-santos In your case, however, you are not exhausting Even so, in your specific case, as you are using a constant in |
I use this pattern all the time, but I wanted exhaustiveness checking, so I switched to enum Letter { alpha, beta, delta }
String letterToString(Letter letter) {
switch (letter) {
case Letter.alpha: return 'α';
case Letter.beta: return 'β';
case Letter.delta: return 'Δ';
}
} But that's a little verbose, especially if you repeat this pattern. So I'm looking forward to switch expressions as part of pattern matching, which would make the following possible: enum Letter { alpha, beta, delta }
String letterToString(Letter letter) => switch (letter) {
case Letter.alpha => 'α';
case Letter.beta => 'β';
case Letter.delta => 'Δ';
}
} Seeing as
For that, Dart would have to have guarantees in place about who can subclass a type. Consider these two files in separate packages, by different authors. // shapes.dart
abstract class Shape { }
class Square extends Shape { }
class Circle extends Shape { }
// Using pattern-matching syntax
String getShapeName(Shape shape) => switch (shape) {
case Square => "Square";
case Circle => "Circle";
} // my_project.dart
import "package:shapes/shapes.dart";
class Rhombus extends Shape { }
void main() {
print(getShapeName(Rhombus()));
} What gets printed? Should Hope that helps! |
I would also recommend using a For the map lookup, the compile could potentially recognize that the |
Thanks, @lrhn and @Levi-Lesches. I already make use of
I am almost sure that I read something related in some issue/proposal about patterns, so I was considering that they will have to solve these kind of issues anyway... |
Yep, the issue I linked (#1696) cites pattern matching as one of the motivating reasons for limiting who can extend a class. That, and the optimized switch statement make me think this is probably a duplicate of pattern matching. I've only looked at the proposal doc I linked, but I see that #546 is sort of an umbrella issue that you might be interested in. |
This does not falls strictly in pattern matching, so it is not a duplicate, although I agree that it could be labeled as part of the patterns feature. However, considering @lrhn comment, I think this is not something that the team is interested in or will spend any resource in, so I am going to close. |
Uh oh!
There was an error while loading. Please reload this page.
Consider the following:
The code above throws, because
letterNames[letter]
isString?
instead ofString
.I know I can simply use bang (
!
) in this case, but it's not costless, and I feel that the compiler could be able to infer that this case is exhaustive and promote the expression toString
.Is this something doable/viable?
Edit:
I changed the title because it could be expanded to any type whose value is not virtually infinite, like
bool
, or even to subtype relations, something like in the following:The text was updated successfully, but these errors were encountered: