Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Address of a temporary in Go?

What's the cleanest way to handle a case such as this:

func a() string {
    /* doesn't matter */
}

b *string = &a()

This generates the error:

cannot take the address of a()

My understanding is that Go automatically promotes a local variable to the heap if its address is taken. Here it's clear that the address of the return value is to be taken. What's an idiomatic way to handle this?

like image 326
Matt Joiner Avatar asked May 10 '12 14:05

Matt Joiner


People also ask

How do I find the address of a variable in Go?

To access the address value (data) represented by a variable, Go provides the & (ampersand) operator which is used in front of the variable name. By doing this, &variable_name expression returns the memory address of the value (data) referenced by variable_name variable.

Are there pointers in Go?

Go has pointers. A pointer holds the memory address of a value. The type *T is a pointer to a T value.

How do I print a pointer value in Go?

In function byval , using pointer q ( *int ), which is a copy of pointer p ( *int ), integer *q ( i ) is set to a new int value 4143 . At the end before returning. the pointer q is set to nil (zero value), which has no effect on p since q is a copy.

What is dereference in Golang?

In Go a pointer is represented using the * (asterisk) character followed by the type of the stored value. In the zero function xPtr is a pointer to an int . * is also used to “dereference” pointer variables. Dereferencing a pointer gives us access to the value the pointer points to.


2 Answers

The address operator returns a pointer to something having a "home", e.g. a variable. The value of the expression in your code is "homeless". if you really need a *string, you'll have to do it in 2 steps:

tmp := a(); b := &tmp

Note that while there are completely valid use cases for *string, many times it's a mistake to use them. In Go string is a value type, but a cheap one to pass around (a pointer and an int). String's value is immutable, changing a *string changes where the "home" points to, not the string value, so in most cases *string is not needed at all.

like image 127
zzzz Avatar answered Oct 06 '22 02:10

zzzz


See the relevant section of the Go language spec. & can only be used on:

  1. Something that is addressable: variable, pointer indirection, slice indexing operation, field selector of an addressable struct, array indexing operation of an addressable array; OR
  2. A composite literal

What you have is neither of those, so it doesn't work.

I'm not even sure what it would mean even if you could do it. Taking the address of the result of a function call? Usually, you pass a pointer of something to someone because you want them to be able to assign to the thing pointed to, and see the changes in the original variable. But the result of a function call is temporary; nobody else "sees" it unless you assign it to something first.

If the purpose of creating the pointer is to create something with a dynamic lifetime, similar to new() or taking the address of a composite literal, then you can assign the result of the function call to a variable and take the address of that.

like image 23
newacct Avatar answered Oct 06 '22 01:10

newacct