Open ltOgt opened 2 years ago
Adding values as an instance member is new (and breaking, you can't also have a static values
member).
It's not a particularly good fit, because while you can often do something from one just enum value, you also (just as frequently in my experience) want to do something without any enum value to being with.
Say, implement an EnumSet<T extends Enum>
, which will be more efficient if you know the number of enum values when the EnumSet
is created, before any element is added.
I'd much rather have a static helper on Enum
, like static List<T> valuesOf<T extends Enum>();
which "magically" and semi-reflection-like extracts the values
list from the enum type.
Then your code would be:
E nextMyEnum<E extends Enum>(E value) =>
value.values[(value.index + 1) % Enum.valuesOf<E>().length];
Oh yeah that would be great
The con of an Enums
class is that every one of the methods could just be static functions on Enum
instead. The class is unnecessary.
For static methods, the con is that extension methods are generally better that static helpers.
That's why name
is already an extension getter on Enum
instances.
The index
getter could be an extension getter (q.v. #1995 discussion).
The List<T> valuesOf<T extends Enum>()
static method is special in that it really is a kind of reflection.
It's not something that can be implemented in plain Dart (not unless we have a global mapping from enum type to values).
It also needs some more design because you can define (with the proposed enum enhancements)
enum Foo<T> {
foo1<int>(),
foo2<double>(),
foo3<String>()
}
and if you then do Enum.valuesOf<Foo<num>>()
, what should it return? It can't return const[Foo.foo1, Foo.foo2, Foo.foo3]
because that doesn't have type List<Foo<num>>
, just List<Foo<Object?>>
.
Would it dynamically create a list of the values that satisfy that type? Like:
static List<T> valuesOf<T extends Enum>() {
List<Enum> values = _magicalLookupValuesConstant<T>();
if (values is List<T>) return values;
return List<T>.unmodifiable(values.whereType<T>());
}
It's non-trivial, sadly :(
Dart enums are amenics and force us to use class
pub enum Option<T> {
None,
Some(T)
}
enum IpAddr {
V4(String),
V6(String)
}
enum IpAddr {
V4(u8, u8, u8, u8),
V6(String)
}
Enums in Rust mean something totally different from whatever we discuss here. In Rust, the concept called "enum" applies to algebraic data types, not values. There's one version of rust enum that supports values (in the same sense as the proposed dart enums), but the values should be all integers. Details
Rust supports the 2 simultaneously, I don't need change version:
enum Foo {
Bar, // 0
Baz = 123, // 123
Quux, // 124
}
let baz_discriminant = Foo::Baz as u32;
assert_eq!(baz_discriminant, 123);
the ADT enum
could be another name, Haskell uses data
and V uses type
By "version", I don't mean "Rust version". It's a "flavor" of enums (why they use the same word for 2 different concepts is beyond me). In the "value" flavor, the said "value" is integer only. The current proposal is about porting java enums - something that is found in java only (no other language I'm aware of copied the concept). I'm wondering why.
EDIT: maybe this thing has something to do with it? Expires in 2024.
it's has to do, but is very verbose and unnecessary, I've never seen it anywhere. The variations I know are Haskell's data
, Rust's enum
, and V's type
(sumtype)
https://github.com/vlang/v/blob/master/doc/docs.md#sum-types
I often wan't to cycle through enums. But I don't think it is possible to write e.g. the following in a way that is re-usable across
enum
sThe abstract 'Enum' looks like this:
If the abstract class defined a getter for values for example, one could do:
Also related: https://stackoverflow.com/a/60459896/6862386