I recently read Global Constant Maps and Slices in Go ( via ), which starts by noting that Go doesn't let you create
const
maps or slices and then works around that by having an access function that returns a constant slice (or map):
const rateLimit = 10func getSupportedNetworks() []string { return []string{"facebook", "twitter", "instagram"} }
When I read the article, my instinctive reaction was that that's not actually a constant because the caller can always change it (although if you call
getSupportedNetworks()
again you get a new clean original slice). Then I thought more about real Go constants like
rateLimit
and realized that they have this behavior too, because any time you use a Go constant, it's materialized into a mutable value .
Obviously if you assign the
rateLimit
constant to a variable, you can then change the variable later; the same is true of assigning it to a struct field. If you call a function and pass
rateLimit
as one argument, the function receives it as an argument value and can change it. If a function returns
rateLimit
, the caller gets back a value and can again change it. This is no different with the slice that
getSupportedNetworks()
returns.
The difference between using
rateLimit
and using the return value from
getSupportedNetworks
is that the latter can be mutated through a second reference without the explicit use of Go pointers:
func main() {
a := rateLimit
b := &a
*b += 10
c := getSupportedNetworks()
d := c
d[1] = "mastodon"
fmt.Println(a, c)
}
But this is not a difference between true Go constants and our emulated constant slice, it's a difference in the handling of the types involved. Maps and slices are special this way, but other Go values are not.
(Slices are also mutable at a distance in other ways .)
PS: Go constants can't have their address taken with '
&
', but they aren't the only sorts of unaddressable values in Go . In theory we could make
getSupportedNetworks()
return an unaddressable value by making its return value be '
[3]string
', as we've seen before ; in practice you almost certainly don't want to do that for various reasons.
(This seems like an obvious observation now that I've thought about it, but I hadn't really thought about it before reading the article and having my reflexive first reaction.)