Comment faire un littéral * int64 dans Go?

J’ai un type de structure avec un champ *int64 .

 type SomeType struct { SomeField *int64 } 

À un moment donné dans mon code, je veux déclarer un littéral de ceci (par exemple, quand je sais que cette valeur doit être 0 ou un 0, vous savez ce que je veux dire)

 instance := SomeType{ SomeField: &0, } 

… sauf que ça ne marche pas

 ./main.go:xx: cannot use &0 (type *int) as type *int64 in field value 

Donc j’essaye ça

 instance := SomeType{ SomeField: &int64(0), } 

… mais ça ne marche pas non plus

 ./main.go:xx: cannot take the address of int64(0) 

Comment puis-je faire cela? La seule solution que je puisse trouver consiste à utiliser une variable d’espace réservé

 var placeholder int64 placeholder = 0 instance := SomeType{ SomeField: &placeholder, } 

Note: la syntaxe &0 fonctionne bien quand c’est un * int au lieu d’un *int64 . Edit: non, ce n’est pas le cas. Désolé pour ça.

Modifier:

Par ailleurs, il y avait trop d’ambiguïté dans ma question. Je cherche un moyen d’ affirmer littéralement un *int64 . Cela pourrait être utilisé à l’intérieur d’un constructeur, ou pour définir des valeurs de structure littérales, ou même comme arguments pour d’autres fonctions. Mais les fonctions d’aide ou l’utilisation d’un type différent ne sont pas des solutions que je recherche.

La spécification de langue de destination ( opérateurs d’adresse ) ne permet pas de prendre l’adresse d’une constante numérique (pas d’une constante non typée ni d’une constante typée ).

L’opérande doit être adressable , c’est-à-dire soit une variable, une indirection de pointeur, soit une opération d’indexation de tranche; ou un sélecteur de champ d’un opérande struct structuré; ou une opération d’indexation de tableau d’un tableau adressable. En tant qu’exception à l’exigence d’adressabilité, x [dans l’expression de &x ] peut également être un littéral composite (éventuellement entre parenthèses).

Pour raisonner pourquoi cela n’est pas autorisé, voir la question connexe: Rechercher l’adresse de constante dans go . Une question similaire (de même non autorisé à prendre son adresse): Comment puis-je stocker la référence au résultat d’une opération dans Go?

Vos options (essayez tous sur le terrain de jeu Go ):

1) Avec new()

Vous pouvez simplement utiliser la fonction new() intégrée pour allouer un nouvel int64 valeur zéro et obtenir son adresse:

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

Mais notez que cela ne peut être utilisé que pour allouer et obtenir un pointeur sur la valeur zéro de tout type.

2) Avec variable auxiliaire

Le plus simple et recommandé pour les éléments non nuls est d’utiliser une variable auxiliaire dont l’adresse peut être prise:

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

3) Avec la fonction d’assistance

Ou si vous en avez besoin plusieurs fois, vous pouvez créer une fonction d’assistance qui alloue et retourne un *int64 :

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

Et en l’utilisant:

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

4) Avec une fonction anonyme à une seule ligne

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

Ou comme alternative (plus courte):

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

5) Avec slalec littéral, indexation et prise d’adresse

Si vous voulez que *SomeField soit différent de 0 , alors vous avez besoin de quelque chose adressable.

Vous pouvez toujours le faire, mais c’est moche:

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

Ce qui se passe ici, c’est qu’une tranche []int64 est créée avec un littéral, avec un élément ( 5 ). Et il est indexé (0ème élément) et l’adresse du 0ème élément est prise. En arrière-plan, un tableau de [1]int64 sera également alloué et utilisé comme tableau de sauvegarde pour la tranche. Donc, il y a beaucoup de passe-partout ici.

6) Avec une structure helper littérale

Examinons l’exception aux exigences d’adressabilité:

En tant qu’exception à l’exigence d’adressabilité, x [dans l’expression de &x ] peut également être un littéral composite (éventuellement entre parenthèses).

Cela signifie que prendre l’adresse d’un littéral composite, par exemple un littéral struct, est acceptable. Si nous le faisons, la structure sera affectée et un pointeur sera obtenu. Mais si tel est le cas, une autre exigence deviendra disponible pour nous: “sélecteur de champ d’un struct operand adressable” . Donc si le struct literal contient un champ de type int64 , on peut aussi prendre l’adresse de ce champ!

Voyons cette option en action. Nous allons utiliser ce type de structure wrapper:

 type intwrapper struct { x int64 } 

Et maintenant nous pouvons faire:

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

Notez que ceci

 &(&intwrapper{6}).x 

signifie ce qui suit:

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

Mais nous pouvons omettre la parenthèse “externe” comme opérateur d’adresse & est appliquée au résultat de l’ expression du sélecteur .

Notez également que ce qui suit se produira (ceci est également une syntaxe valide):

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

7) Avec assistant struct anonyme littéral

Le principe est le même que dans le cas n ° 6, mais nous pouvons également utiliser un littéral struct anonyme, de sorte qu’aucune définition de type de structure assistant / wrapper n’est nécessaire:

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