利用 Go 反射机制实现判断 slice 中是否存在某个 item
为什么需要?
日常开发过程中经常遇到需要判断某个 slice(或者 array)中是否包含某个 item 的情况,比如判断 10 是否在[]int{1,2,3}中
怎么做?
一般最容易想到的方法是遍历 slice 中的每个元素,直到找到了该元素,否则返回 false,如下:
package main
func IsInSlice(value int, sli []int) bool {
for _, v := range sli {
if value == v {
return true
}
}
return false
}
这种方法实现略显笨拙,并且针对不同的数据类型无法通用,如果有不同的数据类型,则容易生成很多相同功能的函数,只是参数不同,这样的话代码可用性并不高。
如何改进
golang 中可以通过 reflect 包中的 TypeOf(), ValueOf()和 DeepEqual()接口对方法进行改进,方法参数使用 interface{}类型,代码实现如下:
package main
import "reflect"
func IsInSlice(value interface{}, sli interface{}) bool {
switch reflect.TypeOf(sli).Kind() {
case reflect.Slice, reflect.Array:
s := reflect.ValueOf(sli)
for i := 0; i < s.Len(); i++ {
if reflect.DeepEqual(value, s.Index(i).Interface()) {
return true
}
}
}
return false
}
瞬间不用再为不同数据类型需要写不同函数而心烦了!
提示
因为反射需要的时间开销比较大,所以通用写法的效率肯定比特定类型的写法低,所以需要根据实际情况来权衡使用,如下截图为 int 类型的基准测试:
原文作者:pyihe
原文链接:https://pyihe.github.io/2020/05/29/Golang%E5%88%A4%E6%96%ADslice%E4%B8%AD%E6%98%AF%E5%90%A6%E5%AD%98%E5%9C%A8%E6%9F%90%E4%B8%AAitem.html
推荐阅读
站长 polarisxu
自己的原创文章
不限于 Go 技术
职场和创业经验
Go语言中文网
每天为你
分享 Go 知识
Go爱好者值得关注
评论