Vic*_*gin 241
你应该使用reflect.DeepEqual()
DeepEqual是Go的==运算符的递归松弛.
DeepEqual报告x和y是否"非常相等",定义如下.如果以下情况之一适用,则相同类型的两个值非常相等.不同类型的值永远不会相等.
当相应的元素非常相等时,数组值非常相等.
如果导出和未导出的相应字段非常相等,则结构值非常相等.
如果两者都是零,则Func值非常相等; 否则他们就不是很平等.
如果它们具有非常相同的具体值,则接口值非常相等.
如果它们是相同的地图对象,或者如果它们具有相同的长度并且它们相应的键(使用Go相等匹配)映射到非常相等的值,则它们是非常相等的.
如果使用Go的==运算符将指针值相等,或者它们指向的值非常相等,则指针值非常相等.
当满足以下所有条件时,切片值非常相等:它们都是零或两者都是非零,它们具有相同的长度,并且它们指向相同底层数组的相同初始条目(即&x [0 ] ==&y [0])或其相应的元素(直到长度)非常相等.注意,非零空切片和零切片(例如,[] byte {}和[] byte(nil))不是非常相等.
其他值 - 数字,bool,字符串和通道 - 如果使用Go的==运算符相等则非常相等.
Ste*_*erg 144
您需要遍历切片中的每个元素并进行测试.未定义切片的等同性.但是,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
}
Run Code Online (Sandbox Code Playgroud)
Aka*_*all 40
这只是使用@ 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))
}
Run Code Online (Sandbox Code Playgroud)
结果:
true
false
Run Code Online (Sandbox Code Playgroud)
Kek*_*mee 20
如果你有两个[]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))
}
Run Code Online (Sandbox Code Playgroud)
这将打印
true
false
Run Code Online (Sandbox Code Playgroud)
bla*_*een 20
该函数现在位于标准库中:slices.Equal。
你不能将==or!=与切片一起使用,但如果你可以将它们与元素一起使用,那么 Go 1.18 包中有一个新函数golang.org/x/exp可以轻松比较两个切片slices.Equal:
Equal 报告两个切片是否相等:长度相同且所有元素相等。如果长度不同,Equal 返回 false。否则,按递增的索引顺序比较元素,并且比较在第一个不相等的对处停止。浮点 NaN 不被视为相等。
包slices导入路径为golang.org/x/exp/slices。exp包内的代码是实验性的,尚未稳定。最终将在 Go 1.19 中移入标准库。
不过,从 Go 1.18 ( playground )开始你就可以使用它了
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
Run Code Online (Sandbox Code Playgroud)
如果切片的元素不允许==and !=,您可以使用slices.EqualFunc并定义对元素类型有意义的任何比较器函数。
如果您有兴趣编写测试,那么github.com/stretchr/testify/assert就是您的朋友。
在文件的最开头导入库:
import (
"github.com/stretchr/testify/assert"
)
Run Code Online (Sandbox Code Playgroud)
然后在测试中执行以下操作:
func TestEquality_SomeSlice (t * testing.T) {
a := []int{1, 2}
b := []int{2, 1}
assert.Equal(t, a, b)
}
Run Code Online (Sandbox Code Playgroud)
提示的错误将是:
Diff:
--- Expected
+++ Actual
@@ -1,4 +1,4 @@
([]int) (len=2) {
+ (int) 1,
(int) 2,
- (int) 2,
(int) 1,
Test: TestEquality_SomeSlice
Run Code Online (Sandbox Code Playgroud)
而现在,这里是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
}
Run Code Online (Sandbox Code Playgroud)