¿Cómo hago un literal * int64 en Go?

Tengo un tipo de estructura con un campo *int64 .

 type SomeType struct { SomeField *int64 } 

En algún punto de mi código, quiero declarar un literal de esto (por ejemplo, cuando sé que dicho valor debe ser 0 o apuntando a un 0, ya sabes a qué 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 bash 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 syntax &0 funciona bien cuando es * int en lugar de *int64 . Editar: no, no. Perdón por esto.

Editar:

Aparentemente había demasiada ambigüedad en mi pregunta. Estoy buscando una forma de declarar literalmente *int64 . Esto podría usarse dentro de un constructor, o para indicar valores de estructura literales, o incluso como argumentos para otras funciones. Pero las funciones auxiliares o el uso de un tipo diferente no son soluciones que estoy buscando.

La especificación de idioma Go ( operadores de dirección ) no permite tomar la dirección de una constante numérica (no de un tipo no escrito ni de una constante escrita ).

El operando debe ser direccionable , es decir, una variable, indirección de puntero o operación de indexación de sector; o un selector de campo de un operando de estructura direccionable; o una operación de indexación de matriz de una matriz direccionable. Como una excepción al requisito de direccionamiento, x [en la expresión de &x ] también puede ser un literal compuesto (posiblemente entre paréntesis).

Para razonar por qué esto no está permitido, consulte la pregunta relacionada: Buscar la dirección de la constante en go . Una pregunta similar (de manera similar, no se permite tomar su dirección): ¿cómo puedo almacenar la referencia al resultado de una operación en Go?

Tus opciones (prueba todo en el campo de juego Go ):

1) Con new()

Simplemente puede usar la función incorporada new() para asignar un nuevo int64 valor int64 y obtener su dirección:

 instance := SomeType{ SomeField: new(int64), } 

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 usar una variable auxiliar cuya dirección se puede tomar:

 helper := int64(2) instance2 := SomeType{ SomeField: &helper, } 

3) Con la función de ayuda

O si necesita esto muchas veces, puede crear una función auxiliar que asigna y devuelve un *int64 :

 func create(x int64) *int64 { return &x } 

Y usándolo:

 instance3 := SomeType{ SomeField: create(3), } 

4) Con una función anónima de una línea

 instance4 := SomeType{ SomeField: func() *int64 { i := int64(4); return &i }(), } 

O como una alternativa (más corta):

 instance4 := SomeType{ SomeField: func(i int64) *int64 { return &i }(4), } 

5) Con el corte literal, indexación y toma de dirección

Si desea que *SomeField sea ​​distinto de 0 , entonces necesita algo direccionable.

Todavía puedes hacer eso, pero eso es feo:

 instance5 := SomeType{ SomeField: &[]int64{5}[0], } fmt.Println(*instance2.SomeField) // Prints 5 

Lo que sucede aquí es un []int64 segmento []int64 se crea con un literal, que tiene un elemento ( 5 ). Y está indexado (0º elemento) y se toma la dirección del 0º elemento. En el fondo, una matriz de [1]int64 también se asignará y usará como la matriz de respaldo para la porción. Así que hay un montón de repetitivo aquí.

6) Con un helper struct literal

Examinemos la excepción a los requisitos de direccionamiento:

Como una excepción al requisito de direccionamiento, x [en la expresión de &x ] también puede ser un literal compuesto (posiblemente entre paréntesis).

Esto significa que tomar la dirección de un literal compuesto, por ejemplo, una estructura literal está bien. Si lo hacemos, tendremos el valor struct 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 el literal struct 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 contenedora:

 type intwrapper struct { x int64 } 

Y ahora podemos hacer:

 instance6 := SomeType{ SomeField: &(&intwrapper{6}).x, } 

Tenga en cuenta que esto

 &(&intwrapper{6}).x 

significa lo siguiente:

 & ( (&intwrapper{6}).x ) 

Pero podemos omitir el paréntesis “externo” como el operador de dirección & se aplica al resultado de la expresión del selector .

También tenga en cuenta que en el fondo sucederá lo siguiente (también es una syntax válida):

 &(*(&intwrapper{6})).x 

7) Con el helper anonymous struct 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 es necesaria una definición de tipo de estructura auxiliar / envoltorio:

 instance7 := SomeType{ SomeField: &(&struct{ x int64 }{7}).x, }