pointers - ¿Cómo obtener el puntero del valor de retorno de la llamada a la función?
go (2)
La respuesta probablemente insatisfactoria es "no puedes hacerlo porque la especificación lo dice".
La especificación dice que para usar
&
en algo tiene que ser
addressable
o un literal compuesto, y para ser direccionable tiene que ser "una operación de indexación indirecta de puntero o de división, o un selector de campo de un operando de estructura direccionable; o una operación de indexación de una matriz direccionable ".
Las llamadas a funciones y llamadas a métodos definitivamente no están en la lista.
En términos prácticos, probablemente se deba a que el valor de retorno de una función puede no tener una dirección utilizable; puede estar en un registro (en cuyo caso definitivamente no es direccionable) o en la pila (en cuyo caso tiene una dirección, pero una que no será válida si se coloca en un puntero que escapa del alcance actual. Para garantizar direccionamiento, Go tendría que hacer más o menos el equivalente exacto de asignarlo a una variable. Pero Go es el tipo de lenguaje que calcula que si va a asignar almacenamiento para una variable será porque usted lo dijo, no porque el el compilador lo decidió mágicamente, por lo que no hace que el resultado de una función sea direccionable.
O podría estar pensando demasiado y simplemente no querían tener un caso especial para funciones que devuelven un valor versus funciones que devuelven múltiples :)
Solo necesito un puntero al tiempo. Tiempo, por lo que el código a continuación parece no válido:
./c.go:5: no se puede tomar la dirección del tiempo. Ahora ()
Solo me pregunto por qué? ¿Hay alguna forma de hacerlo, excepto hacer una asignación a una variable primero y tomar el puntero de la variable?
package main
import "time"
func main() {
_ = &time.Now()
}
No puede tomar directamente la dirección de una llamada a la función (o más precisamente los valores de retorno de la función) como lo describe hobbs.
Hay otra forma pero es fea:
p := &[]time.Time{time.Now()}[0]
fmt.Printf("%T %p/n%v", p, p, *p)
Salida ( Go Playground ):
*time.Time 0x10438180
2009-11-10 23:00:00 +0000 UTC
Lo que sucede aquí es que se crea una
struct
con un literal, que contiene un elemento (el valor de retorno de
time.Now()
), el segmento se indexa (elemento 0) y se toma la dirección del elemento 0.
Entonces, simplemente use una variable local:
t := time.Now()
p := &t
O una función auxiliar:
func ptr(t time.Time) *time.Time {
return &t
}
p := ptr(time.Now())
Que también puede ser una función anónima de una línea:
p := func() *time.Time { t := time.Now(); return &t }()
O como alternativa:
p := func(t time.Time) *time.Time { return &t }(time.Now())
Para aún más alternativas, ver:
¿Cómo hago un literal * int64 en Go?
Consulte también la pregunta relacionada: ¿Cómo puedo almacenar referencias al resultado de una operación en Go?