如果运算符==和!=不是一个选项,我如何检查两个切片是否相等?
package main
import "fmt"
func main() {
s1 := []int{1, 2}
s2 := []int{1, 2}
fmt.Println(s1 == s2)
}
它不使用:
无效的操作:s1 == s2 (slice只能与nil进行比较)
如果运算符==和!=不是一个选项,我如何检查两个切片是否相等?
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)
对于这种比较有一些注意事项,特别是您不能以这种方式比较空切片,并且切片的容量不会进行比较,因此这种“同一性”属性仅在从切片中读取或对严格狭窄的子切片进行切片时才真正有用,因为任何增加切片的尝试都会受到切片容量的影响。不过,能够有效地声明“这两个巨大的内存块实际上是同一个块,是或不是”是非常有用的。
其他回答
现在,这里是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
}
如果你有两个[]字节,使用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
这只是使用@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
试试在围棋游乐场
你应该使用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.
想到了一个妙招,想和大家分享一下。
如果你感兴趣的是两个切片是否相同(即它们在相同的数据区域中使用别名),而不仅仅是相等(一个切片的每个索引上的值等于另一个切片的相同索引上的值),那么你可以用以下方式有效地比较它们:
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)
对于这种比较有一些注意事项,特别是您不能以这种方式比较空切片,并且切片的容量不会进行比较,因此这种“同一性”属性仅在从切片中读取或对严格狭窄的子切片进行切片时才真正有用,因为任何增加切片的尝试都会受到切片容量的影响。不过,能够有效地声明“这两个巨大的内存块实际上是同一个块,是或不是”是非常有用的。