go

What is the specification in Go on implicit type casting?


See this snippet:

var a, b net.IP
if bytes.Equal(a, b) { }

This works, although a and b is not []byte, they are in essense same and compatible.

However, this does not work:

type Code byte
c := Code(123)
buf := []byte{c}

The last statement must be buf := []byte{byte(c)} to compile.

My impression of Go's type system is that it's very rigid to the point of being paranoid. So I wonder what is the EXACT rule of the language that such type casting is not necessary:

if bytes.Equal([]byte(ip1), []byte(ip2)) {...}

Solution

  • This is the relevant section in the spec:

    https://go.dev/ref/spec#Assignability

    For this particular instance: net.IP is a named type whose underlying type is []byte, and bytes.Equal accepts a []byte, which is not a named type, so the assignment works,

    In the second instance, Code is a named type, so you cannot use it as a byte, which is another named type.