Проверка равенства двух срезов

Как проверить, равны ли два среза?

Ответ 1

Вам нужно перебрать каждый элемент в срезе и протестировать. Равенство для ломтиков не определено. Тем не менее, есть функция bytes.Equal если вы сравниваете значения типа []byte.

func testEq(a, b []Type) bool {

    // If one is nil, the other must also be nil.
    if (a == nil) != (b == nil) { 
        return false; 
    }

    if len(a) != len(b) {
        return false
    }

    for i := range a {
        if a[i] != b[i] {
            return false
        }
    }

    return true
}

Ответ 2

Вы должны использовать refle.DeepEqual()

DeepEqual - это рекурсивная релаксация оператора Go ==.

DeepEqual сообщает, являются ли x и y "глубоко равными", определяется следующим образом. Два значения одинакового типа глубоко равны, если применяется один из следующих случаев. Значения различных типов никогда не бывают глубоко равными.

Значения массива глубоко равны, когда их соответствующие элементы глубоко равны.

Значения структур сильно равны, если их соответствующие поля, как экспортированные, так и не экспортированные, глубоко совпадают.

Значения Func глубоко равны, если оба равны нулю; в противном случае они не глубоко равны.

Значения интерфейса глубоко равны, если они содержат глубоко равные конкретные значения.

Значения карты являются глубоко равными, если они являются одним и тем же объектом карты или имеют одинаковую длину, и их соответствующие ключи (соответствующие с помощью равенства Go) отображаются на глубоко равные значения.

Значения указателя глубоко равны, если они равны с помощью оператора Go == или если они указывают на глубоко равные значения.

Значения среза глубоко равны, когда все следующие условия верны: они оба равны нулю или оба не равны нулю, имеют одинаковую длину и либо указывают на одну и ту же начальную запись одного и того же базового массива (то есть & x [0 ] == & y [0]) или соответствующие им элементы (вплоть до длины) глубоко равны. Обратите внимание, что ненулевой пустой слайс и нулевой слайс (например, [] byte {} и [] byte (nil)) не являются глубоко равными.

Другие значения - числа, bools, строки и каналы - глубоко равны, если они равны, используя оператор Go ==.

Ответ 3

Это просто пример использования рефлекса .DeepEqual(), который указан в ответе @VictorDeryagin.

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

}

Результат:

true
false

Попробуйте на Go Playground

Ответ 4

Если у вас есть два []byte, сравните их, используя bytes.Equal. Документация Голанга гласит:

Equal возвращает логическое сообщение о том, что a и b имеют одинаковую длину и содержат одинаковые байты. Нулевой аргумент эквивалентен пустому фрагменту.

Использование:

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

Это напечатает

true
false

Ответ 5

Если вы заинтересованы в написании теста, то github.com/stretchr/testify/assert - ваш друг.

Импортируйте библиотеку в самом начале файла:

import (
    "github.com/stretchr/testify/assert"
)

Затем внутри теста вы делаете:


func TestEquality_SomeSlice (t * testing.T) {
    a := []int{1, 2}
    b := []int{2, 1}
    assert.Equal(t, a, b)
}

Появится сообщение об ошибке:

                Diff:
                --- Expected
                +++ Actual
                @@ -1,4 +1,4 @@
                 ([]int) (len=2) {
                + (int) 1,
                  (int) 2,
                - (int) 2,
                  (int) 1,
Test:           TestEquality_SomeSlice

Ответ 6

И вы все еще можете использовать Sprintf

package main
import "fmt"

type color string

func (color) String() string { return "black" }

func main() {
    slice1 := []color{color("red"), color("green")}
    slice2 := []color{color("blue"), color("yellow")}

    if fmt.Sprintf("%v", slice1) == fmt.Sprintf("%v", slice2) {
        println("not really")
    }
}

Ответ 7

А пока вот https://github.com/google/go-cmp, который

Предполагается, что это более мощная и безопасная альтернатива reflect.DeepEqual для сравнения семантически равных двух значений.

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
}