Je définis une struct ...
type Session struct {
playerId string
beehive string
timestamp time.Time
}
Parfois, je lui attribue une session vide (car nil n'est pas possible)
session = Session{};
Ensuite, je veux vérifier si elle est vide:
if session == Session{} {
// do stuff...
}
Évidemment cela ne fonctionne pas. Comment puis-je l'écrire?
Vous pouvez utiliser == pour comparer avec un littéral composite de valeur zéro car tous les champs sont comparables :
if (Session{}) == session {
fmt.Println("is zero value")
}
En raison de ambiguité dans l'analyse , des parenthèses sont requises autour du littéral composite dans la condition if.
L'utilisation de ==
ci-dessus s'applique aux structures où tous les champs sont comparables . Si la structure contient un champ non comparable (tranche, carte ou fonction), les champs doivent être comparés un par un à leur valeur zéro.
Une alternative à la comparaison de la valeur entière consiste à comparer un champ qui doit être défini sur une valeur autre que zéro dans une session valide. Par exemple, si l’ID du joueur doit être! = "" Dans une session valide, utilisez
if session.playerId == "" {
fmt.Println("is zero value")
}
Voici 3 autres suggestions ou techniques:
Vous pouvez ajouter un champ supplémentaire pour indiquer si la structure a été remplie ou si elle est vide. J'ai intentionnellement nommé ready
et non pas empty
car la valeur zéro d'un bool
est false
, donc si vous créez une nouvelle structure telle que Session{}
son champ ready
sera automatiquement false
et qu'il vous dira la vérité: la structure est pas encore prêt (c'est vide).
type Session struct {
ready bool
playerId string
beehive string
timestamp time.Time
}
Lorsque vous initialisez la structure, vous devez définir ready
sur true
. Votre méthode isEmpty()
n'est plus nécessaire (bien que vous puissiez en créer une si vous le souhaitez) car vous pouvez simplement tester le champ ready
lui-même.
var s Session
if !s.ready {
// do stuff (populate s)
}
La signification de ce champ bool
supplémentaire augmente à mesure que la structure grossit ou si elle contient des champs non comparables (par exemple, slice, map
et valeurs de fonction).
Ceci est similaire à la suggestion précédente, mais il utilise la valeur zéro d'un champ existant qui est considéré invalide lorsque la structure n'est pas vide. La facilité d'utilisation dépend de la mise en œuvre.
Par exemple, si dans votre exemple, votre playerId
ne peut pas être vide string
""
, vous pouvez l'utiliser pour tester si votre structure est vide de la manière suivante:
var s Session
if s.playerId == "" {
// do stuff (populate s, give proper value to playerId)
}
Dans ce cas, il vaut la peine d’incorporer cette vérification dans une méthode isEmpty()
car cette vérification dépend de la mise en oeuvre:
func (s Session) isEmpty() bool {
return s.playerId == ""
}
Et en l'utilisant:
if s.isEmpty() {
// do stuff (populate s, give proper value to playerId)
}
La deuxième suggestion consiste à utiliser un pointeur sur votre structure: *Session
. Les pointeurs peuvent avoir des valeurs nil
, vous pouvez donc les tester:
var s *Session
if s == nil {
s = new(Session)
// do stuff (populate s)
}
Utiliser reflect.deepEqual aussi fonctionne , surtout si vous avez une carte dans la structure
package main
import "fmt"
import "time"
import "reflect"
type Session struct {
playerId string
beehive string
timestamp time.Time
}
func (s Session) IsEmpty() bool {
return reflect.DeepEqual(s,Session{})
}
func main() {
x := Session{}
if x.IsEmpty() {
fmt.Print("is empty")
}
}
Gardez à l'esprit qu'avec les pointeurs à structurer, vous devez déréférencer la variable et ne pas la comparer avec un pointeur sur une structure vide:
session := &Session{}
if (Session{}) == *session {
fmt.Println("session is empty")
}
Vérifiez ceci terrain de je .
Ici aussi, vous pouvez voir qu’une structure contenant une propriété qui est une tranche de pointeurs ne peut pas être comparée de la même manière ...
Comme alternative aux autres réponses, il est possible de faire cela avec une syntaxe similaire à celle que vous aviez initialement voulue si vous le faites via une instruction case
plutôt que if
:
session := Session{}
switch {
case Session{} == session:
fmt.Println("zero")
default:
fmt.Println("not zero")
}