web-dev-qa-db-fra.com

Comment vérifier une structure vide?

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?

77
Michael

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")
}

exemple de terrain de je

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")
}
138
Cerise Limón

Voici 3 autres suggestions ou techniques:

Avec un champ supplémentaire

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).

Utilisation de la valeur zéro d'un champ existant

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)
}

Utilisez le pointeur sur votre structure

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)
}
26
icza

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")
  } 
}
13
Kokizzu

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 ...

2
shadyyx

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")
}

exemple de terrain de je

0
M.L.