如果运算符==和!=不是一个选项,我如何检查两个切片是否相等?

package main

import "fmt"

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

它不使用:

无效的操作:s1 == s2 (slice只能与nil进行比较)


当前回答

想到了一个妙招,想和大家分享一下。

如果你感兴趣的是两个切片是否相同(即它们在相同的数据区域中使用别名),而不仅仅是相等(一个切片的每个索引上的值等于另一个切片的相同索引上的值),那么你可以用以下方式有效地比较它们:

foo := []int{1,3,5,7,9,11,13,15,17,19}

// these two slices are exactly identical
subslice1 := foo[3:][:4]
subslice2 := foo[:7][3:]

slicesEqual := &subslice1[0]  == &subslice2[0]   && 
               len(subslice1) == len(subslice2)

对于这种比较有一些注意事项,特别是您不能以这种方式比较空切片,并且切片的容量不会进行比较,因此这种“同一性”属性仅在从切片中读取或对严格狭窄的子切片进行切片时才真正有用,因为任何增加切片的尝试都会受到切片容量的影响。不过,能够有效地声明“这两个巨大的内存块实际上是同一个块,是或不是”是非常有用的。

其他回答

这只是使用@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

试试在围棋游乐场

想到了一个妙招,想和大家分享一下。

如果你感兴趣的是两个切片是否相同(即它们在相同的数据区域中使用别名),而不仅仅是相等(一个切片的每个索引上的值等于另一个切片的相同索引上的值),那么你可以用以下方式有效地比较它们:

foo := []int{1,3,5,7,9,11,13,15,17,19}

// these two slices are exactly identical
subslice1 := foo[3:][:4]
subslice2 := foo[:7][3:]

slicesEqual := &subslice1[0]  == &subslice2[0]   && 
               len(subslice1) == len(subslice2)

对于这种比较有一些注意事项,特别是您不能以这种方式比较空切片,并且切片的容量不会进行比较,因此这种“同一性”属性仅在从切片中读取或对严格狭窄的子切片进行切片时才真正有用,因为任何增加切片的尝试都会受到切片容量的影响。不过,能够有效地声明“这两个巨大的内存块实际上是同一个块,是或不是”是非常有用的。

如果你有两个[]字节,使用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

您需要遍历切片中的每个元素并进行测试。切片的相等性没有定义。然而,有一个字节。如果比较类型为[]字节的值,则为相等函数。

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
}

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