亲宝软件园·资讯

展开

详解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 接收任意类型的参数,方法内部要对类型做判断;循环遍历仅支持已知固定类型,效率自然要高些。所以就只能忍痛放弃reflect了。

总结

以上就是整理的golang 判断 两个slice 是否相等全部内容,我们可以借助reflect包的reflect.DeepEqual方法来比较两个切片是否相等,但是效率比较低,如果我们确定了slice的类型,我们可以手写遍历循环的方式来比较,相对效率比较高,希望文章能够帮你解决golang 判断 两个slice 是否相等所遇到的程序开发问题。

加载全部内容

相关教程
猜你喜欢
用户评论