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

package main

import "fmt"

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

它不使用:

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


当前回答

现在,这里是https://github.com/google/go-cmp

是一种更强大、更安全的反映方式。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
}

其他回答

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

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
}

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

试试在围棋游乐场

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

你不能对切片使用==或!=,但如果你可以对元素使用==或!=,那么Go 1.18有一个新功能,可以轻松地比较两个切片。平等:

Equal报告两个切片是否相等:长度相同且所有元素相等。如果长度不同,Equal返回false。否则,元素按照递增的索引顺序进行比较,并且比较在第一个不相等的对处停止。浮点nan不被认为是相等的。

切片包的导入路径为golang.org/x/exp/slices。exp包中的代码是实验性的,还不稳定。它最终将被移到Go 1.19的标准库中。

尽管如此,你可以在Go 1.18(游乐场)中使用它

    sliceA := []int{1, 2}
    sliceB := []int{1, 2}
    equal := slices.Equal(sliceA, sliceB)
    fmt.Println(equal) // true

    type data struct {
        num   float64
        label string
    }

    sliceC := []data{{10.99, "toy"}, {500.49, "phone"}}
    sliceD := []data{{10.99, "toy"}, {200.0, "phone"}}
    equal = slices.Equal(sliceC, sliceD)
    fmt.Println(equal) // true

如果片的元素不允许==和!=,您可以使用片。EqualFunc并定义任何对元素类型有意义的比较器函数。

你应该使用reflect.DeepEqual()

DeepEqual is a recursive relaxation of Go's == operator. DeepEqual reports whether x and y are “deeply equal,” defined as follows. Two values of identical type are deeply equal if one of the following cases applies. Values of distinct types are never deeply equal. Array values are deeply equal when their corresponding elements are deeply equal. Struct values are deeply equal if their corresponding fields, both exported and unexported, are deeply equal. Func values are deeply equal if both are nil; otherwise they are not deeply equal. Interface values are deeply equal if they hold deeply equal concrete values. Map values are deeply equal if they are the same map object or if they have the same length and their corresponding keys (matched using Go equality) map to deeply equal values. Pointer values are deeply equal if they are equal using Go's == operator or if they point to deeply equal values. Slice values are deeply equal when all of the following are true: they are both nil or both non-nil, they have the same length, and either they point to the same initial entry of the same underlying array (that is, &x[0] == &y[0]) or their corresponding elements (up to length) are deeply equal. Note that a non-nil empty slice and a nil slice (for example, []byte{} and []byte(nil)) are not deeply equal. Other values - numbers, bools, strings, and channels - are deeply equal if they are equal using Go's == operator.