pointers - online - solidity español
¿Cómo puedo almacenar referencias al resultado de una operación en Go? (3)
Está bien, es difícil describirlo en palabras, pero digamos que tengo un mapa que almacena punteros
int
, y quiero almacenar el resultado de una operación como otra clave en mi hash:
m := make(map[string]*int)
m["d"] = &(*m["x"] + *m["y"])
Esto no funciona y me da el error:
cannot take the address of *m["x"] & *m["y"]
Pensamientos?
El resultado de la adición se coloca en algún lugar transitorio (en la pila) y, por lo tanto, no sería seguro tomar su dirección.
Debería poder evitar esto asignando explícitamente un
int
en el montón para mantener su resultado:
result := make(int)
*result = *m["x"] + *m["y"]
m["d"] = result
En Go, no puede tomar la referencia de un valor literal (conocido formalmente como un valor r). Try lo siguiente:
package main
import "fmt"
func main() {
x := 3;
y := 2;
m := make(map[string]*int)
m["x"] = &x
m["y"] = &y
f := *m["x"] + *m["y"]
m["d"] = &f
fmt.Printf("Result: %d/n",*m["d"])
}
Echa un vistazo a this tutorial.
Un puntero es una dirección de memoria. Por ejemplo, una variable tiene una dirección en la memoria.
El resultado de una operación como
3 + 4
no tiene una dirección porque no hay memoria específica asignada para ello.
El resultado puede vivir en registros de procesador.
Debe asignar memoria cuya dirección puede poner en el mapa. Lo más fácil y directo es crear una variable local para ello.
Ver este ejemplo:
x, y := 1, 2
m := map[string]*int{"x": &x, "y": &y}
d := *m["x"] + *m["y"]
m["d"] = &d
fmt.Println(m["d"], *m["d"])
Salida (pruébalo en Go Playground ):
0x10438300 3
Nota:
Si el código anterior está en una función, la dirección de la variable local (
d
) que acabamos de poner en el mapa continuará viva incluso si regresamos de la función (es decir, si el
map
se devuelve o se crea fuera) Por ejemplo, una variable global).
En Go, es perfectamente seguro tomar y devolver la dirección de una variable local.
El compilador analizará el código y si la dirección (puntero) escapa a la función, se asignará automáticamente en el montón (y no en la pila).
Para obtener más información, consulte
Preguntas frecuentes: ¿Cómo sé si una variable está asignada en el montón o en la pila?
Nota # 2: Hay otras formas de crear un puntero a un valor (como se detalla en esta respuesta: ¿Cómo hago un literal * int64 en Go? ), Pero son solo "trucos" y no son más agradables o más eficientes. Usar una variable local es la forma más limpia y recomendada.
Por ejemplo, esto también funciona sin crear una variable local, pero obviamente no es intuitivo en absoluto:
m["d"] = &[]int{*m["x"] + *m["y"]}[0]
La salida es la misma. Pruébalo en Go Playground .