428 Stimmen

Überprüfen der Gleichheit von zwei Slices

Wie kann ich überprüfen, ob zwei Slices gleich sind, wenn die Operatoren == und != keine Option sind?

package main

import "fmt"

func main() {
    s1 := []int{1, 2}
    s2 := []int{1, 2}
    fmt.Println(s1 == s2)
}

Dies kompiliert nicht mit:

Ungültige Operation: s1 == s2 (Slice kann nur mit nil verglichen werden)

329voto

Victor Deryagin Punkte 11375

Sie sollten reflect.DeepEqual() verwenden

DeepEqual ist eine rekursive Entspannung des == Operators in Go.

DeepEqual gibt zurück, ob x und y "tiefgleich" sind, definiert als folgt. Zwei Werte des identischen Typs sind tiefgleich, wenn einer der folgenden Fälle zutrifft. Werte von unterschiedlichen Typen sind niemals tiefgleich.

Array-Werte sind tiefgleich, wenn ihre entsprechenden Elemente tiefgleich sind.

Struct-Werte sind tiefgleich, wenn ihre entsprechenden Felder, sowohl exportierte als auch nicht exportierte, tiefgleich sind.

Func-Werte sind tiefgleich, wenn beide nil sind; andernfalls sind sie nicht tiefgleich.

Interface-Werte sind tiefgleich, wenn sie tiefgleiche konkrete Werte halten.

Map-Werte sind tiefgleich, wenn sie dasselbe Map-Objekt sind oder wenn sie die gleiche Länge haben und ihre entsprechenden Schlüssel (mit Go-Äquivalenz abgeglichen) auf tiefgleiche Werte abbilden.

Pointer-Werte sind tiefgleich, wenn sie mit dem == Operator gleich sind oder wenn sie auf tiefgleiche Werte zeigen.

Slice-Werte sind tiefgleich, wenn alle der folgenden Bedingungen erfüllt sind: sie sind beide nil oder beide nicht nil, sie haben die gleiche Länge, und entweder sie zeigen auf den gleichen Anfangseintrag des gleichen zugrundeliegenden Arrays (d.h., &x[0] == &y[0]) oder ihre entsprechenden Elemente (bis zur Länge) sind tiefgleich. Beachten Sie, dass ein nicht-nil leerer Slice und ein nil Slice (zum Beispiel, []byte{} und []byte(nil)) nicht tiefgleich sind.

Andere Werte - Zahlen, Bools, Strings und Channels - sind tiefgleich, wenn sie mit dem == Operator in Go gleich sind.

216voto

Stephen Weinberg Punkte 48669

Sie müssen über jedes der Elemente im Slice iterieren und testen. Gleichheit für Slices ist nicht definiert. Es gibt jedoch eine bytes.Equal-Funktion, wenn Sie Werte vom Typ []byte vergleichen.

func testEq(a, b []Type) bool {
    if len(a) != len(b) {
        return false
    }
    for i := range a {
        if a[i] != b[i] {
            return false
        }
    }
    return true
}

98voto

Akavall Punkte 75208

Dies ist nur ein Beispiel, das reflect.DeepEqual() verwendet, wie es in @VictorDeryagins Antwort gegeben ist.

package main

import (
    "fmt"
    "reflect"
)

func main() {
    a := []int {4,5,6}
    b := []int {4,5,6}
    c := []int {4,5,6,7}

    fmt.Println(reflect.DeepEqual(a, b))
    fmt.Println(reflect.DeepEqual(a, c))

}

Ergebnis:

true
false

Probieren Sie es aus im Go Playground

56voto

KeksArmee Punkte 1329

Wenn Sie zwei []byte haben, vergleichen Sie sie mit bytes.Equal. Die Golang-Dokumentation besagt:

Equal gibt einen booleschen Wert zurück, der angibt, ob a und b die gleiche Länge haben und die gleichen Bytes enthalten. Ein nil-Argument ist äquivalent zu einem leeren Slice.

Verwendung:

package main

import (
    "fmt"
    "bytes"
)

func main() {
    a := []byte {1,2,3}
    b := []byte {1,2,3}
    c := []byte {1,2,2}

    fmt.Println(bytes.Equal(a, b))
    fmt.Println(bytes.Equal(a, c))
}

Dies wird gedruckt

true
false

17voto

lk_vc Punkte 1088

Und jetzt hier ist https://github.com/google/go-cmp, das

als eine leistungsstärkere und sicherere Alternative zu reflect.DeepEqual gedacht ist, um zu vergleichen, ob zwei Werte semantisch gleich sind.

package main

import (
    "fmt"

    "github.com/google/go-cmp/cmp"
)

func main() {
    a := []byte{1, 2, 3}
    b := []byte{1, 2, 3}

    fmt.Println(cmp.Equal(a, b)) // true
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X