| > Doesn't that make them type-unsafe? No, it doesn't. Go's enums are type safe. You can't accidentally mix two different kinds of enum values, or accidentally use some random value of type "int" where an enum value is expected. The type system protects you from values of the wrong type being used. This was demonstrated by that Go Playground link. Literals in Go are untyped until they're used. How they're used determines the type, and then they have a very real type, with very real type safety being enforced. So, if you're using a literal "3" where an integer of type "state" is expected, the Go language specifies that the type of "3" is "state". This is an ergonomic issue when you're expecting exhaustive Sum Types, but not a type safety issue. Should all literal integers just always be a specific type? Let's decide that all literals should be of type "int". Great. Now you can't type a large, 64-bit integer literal to pass as a value to a function, because that would overflow the "int" type, even though the argument is desired to be "int64". There are trade-offs to every approach. > In C++ or Haskell, implicitly assigning integer literals like that isn't valid. I can't comment on how Haskell does things, but C++ is more complicated than you seem to think. https://en.cppreference.com/w/cpp/language/integer_literal#T... "The type of the integer literal is the first type in which the value can fit, from the list of types which depends on which numeric base and which integer-suffix was used." Go's approach is equally type safe here. It assigns the type to the literal based on the expression the literal is used in. As I said before: I really wish Go had proper Sum Types. But enums in Go are type safe, contrary to what you have claimed in several comments here. |