How to get return value pointer from function call?

I just need a pointer to time.Time, so the code below seems invalid:

./c.go: 5: cannot accept time address. Now()

I just wonder why? Is there any way to do this, except to assign the variable first and take a pointer to the variable?

package main import "time" func main() { _ = &time.Now() } 
+18
source share
2 answers

Probably an unsatisfactory answer: "you cannot do this because the specification says so." The spectrum says that to use & for something, it must be an addressable or compound literal, and to be addressable, it must be "a variable, pointer pointer or slice index operation or field selector of an address control operand or index operation of an address array array". Functional calls and method calls are certainly not on the list.

In practical terms, this is probably because the return value of a function may not have a useful address; it can be in a register (in this case it is definitely not addressed) or on the stack (in this case it has an address, but one that will not be valid if it places a pointer that goes out of the current area. of targeting, Go should have make pretty much the exact equivalent of assigning it a variable. But Go is a type of language that shows that if it is going to allocate memory for a variable, it will be because you said, and not because the compiler magically decided, so it doesn’t The result of the addressable function.

Or I could change my mind, and they just didn’t want to have a special case for functions that return one value compared to functions that return several :)

+23
source

You cannot directly get the address of the function call (or, more precisely, the return value (s) of the function), as described in hobbs.

There is another way, but it is ugly

 p := &[]time.Time{time.Now()}[0] fmt.Printf("%T %p\n%v", p, p, *p) 

Output ( Go Playground ):

 *time.Time 0x10438180 2009-11-10 23:00:00 +0000 UTC 

Here, a struct with a literal containing one element (the return value is time.Now() ), the fragment is indexed (the 0th element), and the address of the time.Now() element is taken.

So it’s better to just use a local variable:

 t := time.Now() p := &t 

Or helper function:

 func ptr(t time.Time) *time.Time { return &t } p := ptr(time.Now()) 

Which can also be a one-line anonymous function:

 p := func() *time.Time { t := time.Now(); return &t }() 

Or as an alternative:

 p := func(t time.Time) *time.Time { return &t }(time.Now()) 

See even more alternatives:

How do I make * int64 literal in Go?

Also see the related question: How can I save a link to the result of an operation in Go?

+14
source

Source: https://habr.com/ru/post/988820/


All Articles