Implicit enum conversions are a stupid PITA
Yigal Chripun
yigal100 at gmail.com
Thu Mar 25 06:33:07 PDT 2010
Regan Heath Wrote:
> yigal chripun wrote:
> > Here's a Java 5 version with D-like syntax:
> >
> > enum Flag {
> > READ (0x1), WRITE (0x2), OTHER(0x4)
> >
> > const int value;
> > private this (int value) {
> > this.value = value;
> > }
> > }
> >
> > int main(string[] args) {
> > foo(FLAG.READ.value);
> > foo(FLAG.READ.value | FLAG.WRITE.value);
> > return 0;
> > }
> >
> > No conversions required.
>
> Cool. I wasn't aware of that Java feature/syntax - shows how much Java
> I do :p
>
> But.. what is the definition of 'foo' in the above, specifically does it
> take an argument of type Flag? or int?
>
foo's signature in this case would be something like:
void foo(int);
> If the latter, then all you're doing is shifting the conversion. In my
> example it was a cast, in the above it's a property called 'value' which
> converts the "enum" to 'int'.
>
It might do something very similar but it is not the same semantically.
by casting the enum member to an int you say something about its identity vs. a value property is just a property.
For example, I can define a Color Enum that has two properties, an ordinal value and a hex RGB value.
> Interestingly you can do something similar in D...
>
> import std.stdio;
>
> struct Enum { this(int v) { value = v; } int value; }
>
> struct Flag
> {
> Enum READ = Enum(1);
> Enum WRITE = Enum(2);
> Enum OTHER = Enum(4);
> }
>
> static Flag FLAG;
>
> void foo(int flag)
> {
> writefln("flag = %d", flag);
> }
>
> void main()
> {
> foo(FLAG.READ.value);
> foo(FLAG.READ.value|FLAG.WRITE.value);
> }
>
> What I really want is something more like...
>
> import std.stdio;
> import std.string;
>
> struct Enum
> {
> int value;
>
> this(int v)
> {
> value = v;
> }
>
> Enum opBinary(string s:"|")(Enum rhs)
> {
> return Enum(value|rhs.value);
> }
>
> const string toString()
> {
> return format("%d", value);
> }
> }
>
> struct Flag
> {
> Enum READ = Enum(1);
> Enum WRITE = Enum(2);
> Enum OTHER = Enum(4);
> }
>
> static Flag FLAG;
>
> void foo(Enum e)
> {
> writefln("e = %d", e);
> }
>
> void main()
> {
> foo(FLAG.READ);
> foo(FLAG.READ|FLAG.WRITE);
> }
>
> This is only a partial implementation, to complete it I would have to
> manually define all the numeric and logical operators in my Enum struct.
>
> What I want is for D to do all this with some syntactical sugar, eg.
>
> enum FLAG : numeric
> {
> READ = 1, WRITE = 2, OTHER = 4
> }
>
> R
That's not how it's implemented. the enum members are actually singleton instances of anonymous inner-classes. each member can have it's own methods as well as methods defined for the enum type itself.
I can have:
enum SolarSystem { Earth(mass, distance_from_sun), ...}
SolarSystem.Earth.rotate();
etc...
You could implement this in D with structs/classes but it'll take a lot of code. Java does this for you.
More information about the Digitalmars-d
mailing list