String Types
…
The length of a string
s
can be discovered using the built-in functionlen
. The length is a compile-time constant if the string is a constant. A string’s bytes can be accessed by integer indices 0 throughlen(s)-1
. It is illegal to take the address of such an element; ifs[i]
is thei
‘th byte of a string,&s[i]
is invalid.
There are a couple of nuggets in this paragraph.
First, you may recall from our introduction to constants that a constant may represent “… the result value of some built-in functions such as … len
applied to some expressions.
Now we have an example of such an expression: Calling len
on a string constant returns a constant value. So this is valid:
const str = "Hello, World"
const strLen = len(str) // 12
However, this is not:
var str = "Hello, " + name
const strLen = len(str) // Invalid (unless `name` itself is a string constant as well)
Second, the final sentence is interesting for reasons that aren’t immediately obvious.
First note that taking the address of a slice is perfectly valid:
var s = []byte("Hello, World")
var x = &s[3]
fmt.Println(x) // 0xc00001c033 or some other memory location
Now that I have a pointer to a specific byte in my slice, I can do things with it, including modifying it:
var s = []byte("Hello, World")
var x = &s[3]
*x = 'X'
fmt.Println(string(s)) // HelXo, World
But if we could do the same thing with a string, we would violate the immutability trait of strings.
This is why it is impossible to take the address of an element of a string.
Quotes from The Go Programming Language Specification, Version of January 19, 2023