Earlier quoted context omitted.
Setting aside the full enum API, as well as certain optimizations, this is a rough equivalent of the enum I gave: public class Day extends Enum { private int _ordinal; private Day(int ordinal) { this._ordinal = ordinal; } public int ordinal() { return this._ordinal; } public static final Day SUNDAY = new Day(0); // ... public static final Day SATURDAY = new Day(6); } with the added constraint that the Day constructor…
> this is a rough equivalent of the enum I gave Yes, this echos what I stated earlier: "An enum is conceptually the same as you manually typing 1, 2, 3, ... as constants, except the compiler generates the numbers for you automatically" Nice to see that your understanding is growing. > Taking from your examples, the key point is that a Foo is not a Bar. I'm not sure that's a useful point. Nobody thinks class Foo {} cl…
The values of Day are {SUNDAY, ..., SATURDAY} not {0, ..., 6}. We can, of course, establish a 1:1 mapping between those two sets, and the API provides a convenient forward mapping through the ordinal method and a somewhat less convenient reverse mapping through the values static method. However, at runtime, instances of Day are pointers not numbers, and ints outside the range [0, 6] will never be returned by the ordinal method and will cause IndexOutOfBoundsException if used like Day.values()[ordinal].
Tying back to purpose of this thread, Go cannot deliver the same guarantee. Even if we define
type Day int
const (
Sunday Day = iota
// ...
Saturday
)
then we can always construct Day(-1) or Day(7) and we must consider them in a switch statement. It is also trivial to cast to another "enum" type in Go, even if the variant doesn't exist on the other side. This sealed, nonconvertible nature of Java enums makes them "true" enums, which you can call tag-only discriminated unions or whatever if you want, but no such thing exists in Go. In fact, it is not even possible to directly adapt the Java approach, since sealed types of any kind, including structs, are impossible thanks to new(T) being allowed for all types T.