2016-12-22 2 views
2

Ich habe eine Favorites Struktur mit einer Scheibe Feld:Gibt es eine Möglichkeit, eine Struktur mit einem Schnittfeld mit der Nullwertstruktur zu vergleichen?

type Favorites struct { 
    Color string 
    Lunch string 
    Place string 
    Hobbies []string 
} 

und ich habe ein Person, die die andere Struktur enthält:

type Person struct { 
    Name string 
    Favorites Favorites 
} 

Ich mag würde, um zu sehen, ob das Favorites Feld gesetzt Person. Für andere Arten von Feldern, zum Beispiel eine Zeichenfolge oder ein Int, würde ich dieses Feld mit dem Nullwert vergleichen ("" bzw. 0).

Wenn ich versuche, mit dem Null zu vergleichen, wie unten ich den Fehler invalid operation: p2.Favorites == zeroValue (struct containing []string cannot be compared):

p2 := Person{Name: "Joe"} 

zeroValue := Favorites{} 
if p2.Favorites == zeroValue { 
    fmt.Println("Favorites not set") 
} 

Das paßt, was in der Spezifikation definiert (https://golang.org/ref/spec#Comparison_operators).

Gibt es einen solchen Vergleich, abgesehen von einem mühsamen Vergleich jedes einzelnen Feldes (und daran zu denken, es zu aktualisieren, wenn sich die Struktur ändert)?

Eine Option besteht darin, das Feld Favoriten einen Zeiger auf die Struktur anstelle der Struktur selbst zu machen und dann einfach mit Null zu vergleichen, aber dies ist in einer großen Codebasis, also würde ich lieber keine weitreichenden Änderungen vornehmen Fall.

https://play.golang.org/p/d0NSp8eBes

+0

Können Sie erklären, warum Sie nicht zu bevorzugen das Feld 'Favoriten' zu einem Zeiger machen? Wenn Sie sich nicht um die Äquivalenz kümmern und nur versuchen zu überprüfen, ob das Feld überhaupt gesetzt ist, dann scheint dies die beste Option zu sein. – daltonclaybrook

+1

Um zu meinem vorherigen Kommentar hinzuzufügen, würde ich vorschlagen vorsichtig zu sein über die Verwendung des Nullwerts, um "un-set" auch auf anderen Typen zu bezeichnen. 0 kann ein absolut gültiger Wert für ein int-Feld sein. – daltonclaybrook

+0

@daltonclaybrook Es wäre normalerweise die beste Option. In einer großen Codebasis, in der die Struktur überall verwendet wird, würde ich mich mehr um die Änderung kümmern. Auch wenn es viele Strukturfelder in der Struktur gibt, scheint es, als ob ich eine zu einem Zeiger ändere, und aus Gründen der Konsistenz sollte ich wahrscheinlich alle ändern. – stephenbez

Antwort

3

According to this, können Sie reflect.DeepEqual() verwenden, aber wahrscheinlich sollte nur schreiben Sie Ihre eigene:

type Favorites struct { 
    Color string 
    Lunch string 
    Place string 
    Hobbies []string 
} 

func (favs *Favorites) Equals(other *Favorites) bool { 
    color_eq := favs.Color == other.Color 
    lunch_eq := favs.Lunch == other.Lunch 
    place_eq := favs.Place == other.Place 
    hobbies_eq := len(favs.Hobbies) == len(other.Hobbies) 
    if hobbies_eq { // copy slices so sorting won't affect original structs 
     f_hobbies := make([]string, len(favs.Hobbies)) 
     o_hobbies := make([]string, len(other.Hobbies)) 
     copy(favs.Hobbies, f_hobbies) 
     copy(other.Hobbies, o_hobbies) 
     sort.Strings(f_hobbies) 
     sort.Strings(o_hobbies) 
     for index, item := range f_hobbies { 
      if item != o_hobbies[index] { 
       hobbies_eq = false 
      } 
     } 
    } 
    return (color_eq && lunch_eq && place_eq && hobbies_eq) 
} 

es dann rufen Sie mit:

p2.Favorites.Equals(zeroValue) 
+0

Müssen die Arrays vor dem Vergleich ihrer Werte sortiert werden? –

+0

@AlexKroll Guter Punkt, bearbeitet. – Will

Verwandte Themen