In my application I will frequently pass references to a static string. I wish to avoid having Go allocate memory for each call, but I failed to get the address to my string literal.
Why is it not possible to take the address of a string literal (see test1()
in the example below)? Have I misunderstood the syntax, or is it a limitation due to the internal workings of Go?
If not possible, what would be the best solution?
test2()
works, but will it allocate memory for the var hej
each time?
test3()
will not allocate any new memory, but I wish to avoid clutter outside the function.
package main
import "fmt"
var konnichiwa = `こんにちは世界`
// Gives the compile error `cannot take the address of "Hello world"`
func test1() (*string) { return &`Hello world` }
// Works fine
func test2() (*string) {
hej := `Hej världen`
return &hej
}
func test3() (*string) { return &konnichiwa }
func main(){
fmt.Println(*test1())
fmt.Println(*test2())
fmt.Println(*test3())
}
Thanks for help!
For the question of the best solution for your situation of passing around "static" strings,
It's tempting to give the advice "don't worry about allocating strings" because that's actually true in the case you're describing where the same string is passed around, perhaps many times. It general though, it's really good to think about memory use. It's just really bad to guess, and even worse to guess based on experience with another language.
Here's a modified version of your program. Where do you guess that memory is allocated?
package main
import "fmt"
var konnichiwa = `こんにちは世界`
func test1() *string {
s := `Hello world`
return &s
}
func test2() string {
return `Hej världen`
}
func test3() string {
return konnichiwa
}
func main() {
fmt.Println(*test1())
fmt.Println(test2())
fmt.Println(test3())
}
Now ask the compiler:
> go tool 6g -S t.go
(I named the program t.go.) Search the output for calls to runtime.new. There's only one! I'll spoil it for you, it's in test1.
So without going off on too much of a tangent, the little look at the compiler output indicates that we avoid allocation by working with the string type rather than *string.