详解Golang如何比较两个slice是否相等
1个俗人 人气:0前言
开发中经常会遇到需要比较两个slice
包含的元素是否完全相等的情况,在golang
中是不能够直接通过 ==
来判断两个切片是否相等的,我们通常会通过两种方法去比较切片是否相等,这里通过几个示例来看一下这两种方法,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
判断两个[]byte是否相等
因为在bytes
标准库中提供了[]byte
的比较方法,所以我们不再需要重复造轮子了;示例如下:
package main import ( "bytes" "fmt" ) func main() { a := []byte{1,2,3} b := []byte{1,2} c := []byte{1,2,3} fmt.Println(bytes.Equal(a,b)) fmt.Println(bytes.Equal(a,c)) }
执行代码输出如下:
使用reflect判断slice是否相等
我们还可以借助reflect包的reflect.DeepEqual方法来比较两个切片是否相等。这个写法很简单:
// ReflectDeepEqual 直接使用 reflect 包的 reflect.DeepEqual 方法进行比较 func StringSliceReflectEqual(a, b []string) bool { return reflect.DeepEqual(a, b) }
手写循环遍历比较
我们都知道Golang中reflect效率很低,使用reflect通常需要付出性能代价,如果我们确定了slice的类型,那么自己实现slice的相等判断相对来说也不是那么麻烦:
// LoopCompare 循环遍历比较 // 先比较两个数的长度是否相等 // 再循环遍历每一个元素进行比较 func LoopCompare(a, b []int) bool { if len(a) != len(b) { return false } //与reflect.DeepEqual的结果保持一致:[]int{} != []int(nil) if (a == nil) != (b == nil) { return false } for i, v := range a { if v != b[i] { return false } } return true }
性能比较
借助Benchmark来简单的测试比较下二者的性能。
package test import ( "reflect" "testing" ) var ( testA = []int{1,3,5,9,11,13} testB = []int{1,3,5,9,11,13,17,23} ) // BenchmarkReflectDeepEqual 测试 reflect.DeepEqual 效率 func BenchmarkReflectDeepEqual(b *testing.B) { for n := 0; n < b.N; n++ { ReflectDeepEqual(testA, testB) } } // BenchmarkLoopCompare 测试 循环比较 效率 func BenchmarkLoopCompare(b *testing.B) { for n := 0; n < b.N; n++ { LoopCompare(testA, testB) } }
在测试文件所在目录执行go test -bench=.
命令
Benchmark对比测试结果:
根据测试结果我们可以得到:
- 使用reflect的方式,649 ns完成一次操作;
- 使用循环遍历的方式,12.7 ns完成一次比较,效率对比十分明显。
原因在于reflect 接收任意类型的参数,方法内部要对类型做判断;循环遍历仅支持已知固定类型,效率自然要高些。所以就只能忍痛放弃reflect了。
总结
以上就是整理的golang 判断 两个slice 是否相等全部内容,我们可以借助reflect包的reflect.DeepEqual方法来比较两个切片是否相等,但是效率比较低,如果我们确定了slice的类型,我们可以手写遍历循环的方式来比较,相对效率比较高,希望文章能够帮你解决golang 判断 两个slice 是否相等所遇到的程序开发问题。
加载全部内容