Ich definiere eine Struktur ...
type Session struct {
playerId string
beehive string
timestamp time.Time
}
Manchmal weise ich ihm eine leere Sitzung zu (weil Null nicht möglich ist)
session = Session{};
Dann möchte ich überprüfen, ob es leer ist:
if session == Session{} {
// do stuff...
}
Offensichtlich funktioniert das nicht. Wie schreibe ich es?
Antworten:
Sie können == verwenden, um mit einem zusammengesetzten Nullwert-Literal zu vergleichen, da alle Felder vergleichbar sind :
Spielplatz Beispiel
Aufgrund einer Parsing-Mehrdeutigkeit sind in der if-Bedingung Klammern um das zusammengesetzte Literal erforderlich.
Die Verwendung von
==
oben gilt für Strukturen, bei denen alle Felder vergleichbar sind . Wenn die Struktur ein nicht vergleichbares Feld (Slice, Map oder Funktion) enthält, müssen die Felder einzeln mit ihren Nullwerten verglichen werden.Eine Alternative zum Vergleichen des gesamten Werts besteht darin, ein Feld zu vergleichen, das in einer gültigen Sitzung auf einen Wert ungleich Null gesetzt werden muss. Wenn beispielsweise die Spieler-ID in einer gültigen Sitzung! = "" Sein muss, verwenden Sie
quelle
session
es kein Null ist*Session
, verwenden Sieif (Session{} == *session {
.struct containing []byte cannot be compared
weil meine Struktur ein Byte-Slice enthält.==
Vergleich mit Slice-Feldern fehl. Verwenden Sie zum Vergleichen dieser Strukturen entwederreflect.DeepEqual
etwas oder betrachten Sie etwas Spezielleres, wie hier beschrieben: stackoverflow.com/questions/24534072/…Hier sind 3 weitere Vorschläge oder Techniken:
Mit einem zusätzlichen Feld
Sie können ein zusätzliches Feld hinzufügen, um festzustellen, ob die Struktur ausgefüllt wurde oder leer ist. Ich habe es absichtlich benannt
ready
und nicht,empty
weil der Nullwert von abool
istfalse
. Wenn Sie also eine neue Struktur wieSession{}
dasready
Feld erstellen, wird diese automatisch angezeigtfalse
und es wird Ihnen die Wahrheit sagen: dass die Struktur noch nicht fertig ist (sie ist leer).Wenn Sie die Struktur zu initialisieren, müssen Sie Satz
ready
antrue
. IhreisEmpty()
Methode wird nicht mehr benötigt (obwohl Sie eine erstellen können, wenn Sie möchten), da Sie nur dasready
Feld selbst testen können.Die Bedeutung dieses einen zusätzlichen
bool
Feldes nimmt zu, wenn die Struktur größer wird oder wenn sie Felder enthält, die nicht vergleichbar sind (z. B. Slice-map
und Funktionswerte).Verwenden des Nullwerts eines vorhandenen Feldes
Dies ähnelt dem vorherigen Vorschlag, verwendet jedoch den Nullwert eines vorhandenen Felds, das als ungültig betrachtet wird wenn die Struktur nicht leer ist. Die Verwendbarkeit hängt von der Implementierung ab.
Wenn Sie in Ihrem Beispiel beispielsweise
playerId
nicht leer sein könnenstring
""
, können Sie damit testen, ob Ihre Struktur wie folgt leer ist:In diesem Fall lohnt es sich, diese Prüfung in eine
isEmpty()
Methode aufzunehmen, da diese Prüfung implementierungsabhängig ist:Und damit:
Verwenden Sie den Zeiger für Ihre Struktur
Der zweite Vorschlag ist, einen Zeiger auf Ihre Struktur zu verwenden :
*Session
. Zeiger könnennil
Werte haben, sodass Sie sie testen können:quelle
Mit reflect.deepEqual auch funktioniert , vor allem , wenn Sie Karte innerhalb der Struktur haben
quelle
Beachten Sie, dass Sie bei Zeigern auf struct die Variable dereferenzieren und nicht mit einem Zeiger auf leere struct vergleichen müssen:
Überprüfen Sie diesen Spielplatz .
Auch hier können Sie sehen, dass eine Struktur, die eine Eigenschaft enthält, die ein Teil von Zeigern ist, nicht auf die gleiche Weise verglichen werden kann ...
quelle
Alternativ zu den anderen Antworten ist es möglich, dies mit einer Syntax zu tun, die der ursprünglich beabsichtigten ähnelt, wenn Sie dies über eine
case
Anweisung und nicht über Folgendes tunif
:Spielplatz Beispiel
quelle
Nur eine kurze Ergänzung, denn ich habe heute das gleiche Problem angegangen:
Mit Go 1.13 ist es möglich, die neue
isZero()
Methode zu verwenden:Ich habe dies nicht in Bezug auf die Leistung getestet, aber ich denke, dass dies schneller sein sollte als ein Vergleich über
reflect.DeepEqual()
.quelle
Vielleicht so etwas wie diese
quelle