Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reference to string literals in Go

Tags:

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!

like image 714
ANisus Avatar asked Jun 18 '12 18:06

ANisus


People also ask

Is string a reference type in Go?

In this sense, the correct answer would be: strings are passed by reference. The built in string type is a value type.

What is a string literal in Go programming?

String literals A string literal represents a string constant obtained from concatenating a sequence of characters. There are two forms: raw string literals and interpreted string literals. Raw string literals are character sequences between back quotes, as in `foo` .

How many string literals are used in Go programming?

Go supports two styles of string literals, the double-quote style (or interpreted literals) and the back-quote style (or raw string literals). The zero values of string types are blank strings, which can be represented with "" or `` in literal. Strings can be concatenated with + and += operators.


1 Answers

Taking the address of a literal (string, number, etc) is illegal because it has ambiguous semantics.

Are you taking the address of the actual constant? Which would allow the value to be modified (and could lead to a runtime error) or do you want to allocate a new object, copy the constant over and get the address to the new version?

This ambiguity does not exist in the case of test2 since you are dealing with an existing variable of which the semantics are clearly defined. The same would not work if the string was defined as const.

The language spec avoids this ambiguity by explicitly not allowing what you are asking for. The solution is test2. While it is slightly more verbose, it keeps the rules simple and clean.

Of course, every rule has its exceptions, and in Go this concerns composit literals: The following is legal and defined as such in the spec:

func f() interface{} {     return &struct {         A int         B int     }{1, 2}  } 
like image 65
jimt Avatar answered Sep 27 '22 20:09

jimt