Tengo un tipo de estructura con un *int64
campo.
type SomeType struct {
SomeField *int64
}
En algún momento de mi código, quiero declarar un literal de esto (digamos, cuando sé que dicho valor debe ser 0, o apuntando a un 0, ya sabes a lo que me refiero)
instance := SomeType{
SomeField: &0,
}
... excepto que esto no funciona
./main.go:xx: cannot use &0 (type *int) as type *int64 in field value
Así que intento esto
instance := SomeType{
SomeField: &int64(0),
}
... pero esto tampoco funciona
./main.go:xx: cannot take the address of int64(0)
¿Cómo hago esto? La única solución que se me ocurre es usar una variable de marcador de posición
var placeholder int64
placeholder = 0
instance := SomeType{
SomeField: &placeholder,
}
Nota: la Editar: no, no lo hace. Perdón por esto.&0
sintaxis funciona bien cuando es un * int en lugar de un *int64
.
Editar:
Aparentemente, había demasiada ambigüedad en mi pregunta. Estoy buscando una manera de decir literalmente a *int64
. Esto podría usarse dentro de un constructor, o para indicar valores de estructuras literales, o incluso como argumentos para otras funciones. Pero las funciones auxiliares o el uso de un tipo diferente no son las soluciones que estoy buscando.
var _ *int64 = pointer.Int64(64)
Respuestas:
La especificación del lenguaje Go ( operadores de direcciones ) no permite tomar la dirección de una constante numérica (no de un sin tipo ni de un escrito constante).
Para razonar por qué esto no está permitido, consulte la pregunta relacionada: Buscar la dirección de la constante en marcha . Una pregunta similar (tampoco se permite tomar su dirección): ¿Cómo puedo almacenar una referencia al resultado de una operación en Go?
Tus opciones (prueba todas en Go Playground ):
1) Con
new()
Simplemente puede usar la
new()
función incorporada para asignar un nuevo valor ceroint64
y obtener su dirección:Pero tenga en cuenta que esto solo se puede usar para asignar y obtener un puntero al valor cero de cualquier tipo.
2) Con variable auxiliar
Lo más simple y recomendado para elementos distintos de cero es utilizar una variable auxiliar cuya dirección se pueda tomar:
3) Con función auxiliar
Nota: Las funciones auxiliares para adquirir un puntero a un valor distinto de cero están disponibles en mi
github.com/icza/gox
biblioteca, en elgox
paquete, por lo que no tiene que agregarlas a todos sus proyectos donde las necesite.O si lo necesita muchas veces, puede crear una función auxiliar que asigne y devuelva un
*int64
:Y usándolo:
Tenga en cuenta que en realidad no asignamos nada, el compilador Go lo hizo cuando devolvimos la dirección del argumento de la función. El compilador Go realiza análisis de escape y asigna variables locales en el montón (en lugar de en la pila) si pueden escapar de la función. Para obtener más información, consulte ¿Es seguro devolver una porción de una matriz local en una función Go?
4) Con una función anónima de una sola línea
O como alternativa (más corta):
5) Con literal de corte, indexación y toma de dirección
Si quieres
*SomeField
ser diferente a0
, entonces necesitas algo direccionable.Todavía puedes hacer eso, pero eso es feo:
Lo que sucede aquí es que
[]int64
se crea un segmento con un literal, que tiene un elemento (5
). Y se indexa (elemento 0) y se toma la dirección del elemento 0. En segundo plano[1]int64
, también se asignará una matriz de y se utilizará como matriz de respaldo para el segmento. Así que hay mucho texto estándar aquí.6) Con una estructura de ayuda literal
Examinemos la excepción a los requisitos de direccionabilidad:
Esto significa que tomar la dirección de un literal compuesto, por ejemplo, un literal de estructura está bien. Si lo hacemos, tendremos el valor de la estructura asignado y un puntero obtenido. Pero si es así, otro requisito estará disponible para nosotros: "selector de campo de un operando de estructura direccionable" . Entonces, si la estructura literal contiene un campo de tipo
int64
, ¡también podemos tomar la dirección de ese campo!Veamos esta opción en acción. Usaremos este tipo de estructura de envoltura:
Y ahora podemos hacer:
Tenga en cuenta que esto
significa lo siguiente:
Pero podemos omitir el paréntesis "externo" ya que el operador de dirección
&
se aplica al resultado de la expresión del selector .También tenga en cuenta que en segundo plano sucederá lo siguiente (esta también es una sintaxis válida):
7) Con ayuda de estructura anónima literal
El principio es el mismo que con el caso n. ° 6, pero también podemos usar un literal de estructura anónimo, por lo que no se necesita una definición de tipo de estructura auxiliar / contenedor:
fuente
instance
objetos diferentes apuntarían a dosint64
s diferentes . Pero parece cumplir adecuadamente con la intención de los OP&[]int64{2}[0]
creo que, según la descripción de constantes en blog.golang.org/constants, esto debería funcionar como&0
.instance
objetos diferentesint64
apuntaran al mismo y uno modificara el objeto puntiagudo, ambos cambiarían. ¿Y si ahora usa el mismo literal para crear un terceroinstance
? La misma dirección ahora apuntaría a unint64
valor diferente ... por lo que debería usarse una dirección diferente, pero entonces ¿por qué usar la misma en el caso de las 2 primeras?Utilice una función que devuelva una dirección de una variable int64 para resolver el problema.
fuente