Live data from Hacker News

Compile-time safety for enumerations in Go

vladimir.varank.in

111–116 of 116 posts

Re: Compile-time safety for enumerations in Go

#111
post #19

Unfortunately not. func main() { c := color.Red cptr := (*string)(&c) *cptr = "orange" PrintColor(c) // successfully compiles, and prints "orange" }

It's the game of the mouse and the cat :-D We can change the package color like this : package color type Color interface { void() } type color struct { v string } func (c color) void() {} func (c color) String() string { return c.v } var ( Red color = color{"red"} Green color = color{"green"} Blue color = color{"blue"} )

    func fn(c color.Color) {
     switch c {
     case color.Red, color.Green, color.Blue:
      log.Printf("c=%#+v -- OK", c)
     default:
      log.Printf("c=%#+v -- should not be possible", c)
     }
    }
    
    func main() {
     var c color.Color
     fn(c)
    }    
Output:

    c= -- should not be possible
:shrug:

Re: Compile-time safety for enumerations in Go

#112
post #19

Unfortunately not. func main() { c := color.Red cptr := (*string)(&c) *cptr = "orange" PrintColor(c) // successfully compiles, and prints "orange" }

In this example, *cptr is a color by contract. A Color is a type alias of a string. *cptr is a string. Interfaces match.

Technically not a type alias, just a normal type declaration. But yes, this is my point: you can't assume that an enum type will always be one of a fixed set of values that you've defined. You always have to do at least a little bit of runtime validation of the parameter. It's unavoidable.

Re: Compile-time safety for enumerations in Go

#113
post #112

Earlier quoted context omitted.

In this example, *cptr is a color by contract. A Color is a type alias of a string. *cptr is a string. Interfaces match.

Technically not a type alias, just a normal type declaration. But yes, this is my point: you can't assume that an enum type will always be one of a fixed set of values that you've defined. You always have to do at least a little bit of runtime validation of the parameter. It's unavoidable.

alias and type redefinitions are conceptually the same. int and int_t are conceptually the same. I’m going to assume it’s my type, as defined in the signature of my method you’re calling. If you don’t adhere to the contract then the onus is on you. I’ll check existence, I’ll check conformity, but I won’t check that your string = my string.

Re: Compile-time safety for enumerations in Go

#114
post #90

Earlier quoted context omitted.

It is enforced by the compiler, what it doesn't do is guarantee it at runtime. I agree with you on the enums. Go doesn't have a reliable enum construct. But the argument that I, the library author, must validate and check against any possible type of "color" you, the program author, can come up with is just crazy talk. I'll provide a Color type, I'll even pre-define some colors for you, but if you send me a Color tha…

It literally isn't enforced by the compiler, because I can compile code which is invalid.

It’s not invalid because a string is a string. You didn’t invent a new type.

Re: Compile-time safety for enumerations in Go

#115
post #112

Earlier quoted context omitted.

Technically not a type alias, just a normal type declaration. But yes, this is my point: you can't assume that an enum type will always be one of a fixed set of values that you've defined. You always have to do at least a little bit of runtime validation of the parameter. It's unavoidable.

alias and type redefinitions are conceptually the same. int and int_t are conceptually the same. I’m going to assume it’s my type, as defined in the signature of my method you’re calling. If you don’t adhere to the contract then the onus is on you. I’ll check existence, I’ll check conformity, but I won’t check that your string = my string.

> alias and type redefinitions are conceptually the same.

In Go, they are not. Aliases establish precise equivalence between types, type redefinitions establish new types altogether.

Post reply on HN