检查两个切片的相等性

时间:2013-03-09 14:46:39

标签: go go-reflect

如何检查两个切片是否相等?

6 个答案:

答案 0 :(得分:233)

您应该使用reflect.DeepEqual()

  

DeepEqual是Go的==运算符的递归放宽。

     

DeepEqual报告x和y是否“非常相等”,定义为   如下。如果其中一个相同类型的两个值非常相等   以下情况适用。不同类型的值永远不会深刻   相等。

     

当相应的元素相同时,数组值非常相等   非常平等。

     

结构值如果相应的字段两者都非常相等   出口和未出口,是非常平等的。

     

如果两者都是零,则Func值非常相等;否则他们不是   非常平等。

     

如果它们具有非常相同的混凝土,则界面值非常相等   值。

     

如果它们是相同的地图对象或它们是相同的,则地图值非常相等   具有相同的长度和相应的键(使用Go匹配   平等)映射到非常相等的价值观。

     

如果使用Go的==它们相等,则指针值非常相等   运营商或他们是否指出了相同的价值观。

     

当满足以下所有条件时,切片值非常相等:它们   都是零或两者都是零,它们具有相同的长度,也可以   它们指向相同底层数组的相同初始条目   (即& x [0] ==& y [0])或其对应的元素(最多为   长度)是非常平等的。注意,非零空切片和零   slice(例如,[] byte {}和[] byte(nil))不是很相等。

     

其他价值观 - 数字,布尔,字符串和频道 - 非常深刻   如果它们使用Go的==运算符相等则相等。

答案 1 :(得分:130)

您需要遍历切片中的每个元素并进行测试。未定义切片的等同性。但是,如果要比较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 :(得分:34)

这只是使用@ VictorDeryagin答案中给出的reflect.DeepEqual()的例子。

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

答案 3 :(得分:16)

如果您有两个[]byte,请使用bytes.Equal进行比较。 Golang文档说:

  

Equal返回一个布尔值,报告a和b是否长度相同并包含相同的字节。 nil参数相当于一个空切片。

用法:

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

答案 4 :(得分:2)

现在,这里是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
}

答案 5 :(得分:0)

如果您对编写测试感兴趣,那么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