-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
RFC: Enum trait #284
Comments
Hello, apologies for reviving an old entry (I hope I'm not breaking any rules): what is the latest state of affairs on this subject? Are there (any plans for) traits implementable for Enums that allow you to access the tag number (preferably without consuming the enum in the process)? My use case is a piece of code that can take any type (which it assumes/hopes to be an enum), and internally allocates an array whose length is the number of variants of the enum type - that is to say for: enum Something { A, B, C } An array of 3 would be allocated. To do this I have put together a trait "EnumTag" which provides the methods "tag_number(&self) -> usize" and "max_tag_number() -> usize". I thought this would be relatively trivial to implement, but then it turns out that (using the previous enum as an example): impl EnumTag for Something { That implementation of tag_number is now illegal, as "as usize" now consumes self, whereas from old code examples online (and prior experience) I'm lead to believe that it used to be possible to write the above? But anyway, I digress: are there any plans/thoughts on automatically derivable traits for enums that provide features such as the EnumTag example above? (or similar?) Please let me know if this is the wrong place to ask. |
You could |
@omaskery You just need to Otherwise, you're on the right track, and what you're doing should compile on stable Rust today (the array you're trying to allocate will have to be a |
@withoutboats Fantastic! I'll try that now, thank you. And @Enamex, thank you both for taking the time to answer! On a similar note, I stumbled upon https://github.com/rust-lang/rfcs/blob/master/text/0639-discriminant-intrinsic.md moments after posting my initial comment (how silly I felt!) so that's interesting, too :) |
I find myself wanting to iterate over the variants of enums often, I'd love to see this get into Rust. |
Same here; in addition, I often need functionalities like Haskell's |
You can do this with
Links: |
Just my 2 cents: For a personal project, I needed a similar thing, which I encapsulated into an own crate, It can be used to declare a C-like enum as follows:
And will then allow you to do things like the following:
|
In the domain I work in, data modeling, we need to represent each of the elements that exists in our system's universe. I'd like to make these elements an enum so that I can have verification that all possibilities are covered. But in order to do this, I need to be able to iterate through the possibilities and to count them, so that I can store my measurements, for example, in a packed array of doubles. This use case is treating the enum to make a static, perfect hash that also is typechecked. |
For now, you can write a macro which implements that iterator as well as the enum, I've written something similar before. Here's an example: https://is.gd/1hw4Tn |
Am I correct in understanding that this issue has not had an RFC written for it in the currently expected manner, and that if one was written then iterable enums have a better chance of making it intro Rust as a built-in feature? The alternatives suggested above work for enums where the variants have no payload: enum Foo {
NoPayloadA,
NoPayloadB,
} as opposed to enum ByteFoo {
BytePayloadA(u8),
BytePayloadB(u8),
} but given that we can iterate over the values of a given enum, then we should be able to iterate over enum with payloads that can be iterated over. For example: enum Foo {
FooA,
FooB,
}
enum Bar {
BarA,
BarB,
}
enum Baz {
BazFoo(Foo),
BazBar(Bar)
} if given the preceding code we could iterate over In fact, it seems like if this was implemented in such a way that built-in types could be iterated over as well, then all 512 possible values of my |
Since iteration is only possible on enums where every variant has the same type, if this were to be a built-in feature in standard Rust it would make changing a variant's type a potentially breaking API change even on variants that no one is supposed to use. For that reason, I believe this feature should be opt-in via some kind of The status quo is that custom derive macros have been written to achieve this for no-payload enums. Is there any reason a similar custom derive macro could not be written for all same-payload enums? I don't know of any fundamental reason why they shouldn't be able to do that. |
Some additional possible functionality for this trait: trait Enum {
// Total enum items count
fn len(&self) -> usize;
// call of std::mem::discriminant() with additional typecheck.
fn ordinal(item: Self::Item) -> usize;
} |
I'm a new Rust user, hopefully it's appropriate to add my 2¢ here! It seems like Rust enums are really algebraic sum types, which is great, but C-style or particularly Java-style enums (symbolic names for a set of hard-coded constants) are not very well served. Java's Enum classes are excellent. Rust could really use something similar. For the basic functionality, there's "custom discriminants for field-less enumerations" -- tucked away in the reference and not even mentioned in the Rust Book. It took me a while to find this! The big missing features are conversion to and from strings, and iteration through all the constants. Iteration is the most important because it can be used to implement string conversions (i.e. iterate through the enum values to build a lookup table). There are various crates available for doing various bits of this, but it seems like such a key feature that it would be good to pull this into the standard library. If there were a standard |
guys sorry to bother but is this happen yet? something like |
thoughts...
|
An auto trait is problematic because I may not guarantee how many variants are there, their order, or anything like that. Adding a field would change An auto trait is also problematic because new auto traits have other implications on generic code (AFAIU). |
Hey, I am quite new to Rust but couldn't we use Default::default() for this? |
To add, there are some popular crates that implement some of the desired features. The crate The crate I also found the crate There is also the I think it would be great if Rust could create a trait for the standard library that mirrored the API seen in |
Issue by ghost
Sunday Mar 17, 2013 at 02:56 GMT
For earlier discussion, see rust-lang/rust#5417
This issue was labelled with: A-libs, A-traits, B-RFC in the Rust repository
Since I've been doing some work with the deriving code in libsyntax, I thought I'd solicit opinions on adding a new trait to libcore:
Obviously, this would be most useful for
enum
s with only nullary variants, but other enumerable types could take advantage of it as well (bool::all_values
currently serves the same purpose).This would make it possible to write
instead of
A standard implementation for
enum
s with only nullary variants would be made available through#[deriving(Enum)]
, and a default method (or utility trait/impl until those are working) would be provided for obtaining all the values in a vector. It might be beneficial to have astatic fn cardinality() -> Option<uint>
method on the trait as well.If the trait name is too easily confused with the keyword, another option is
Enumerable
.The text was updated successfully, but these errors were encountered: