Go 中不像 Python 那样可以通过 a in []
判断数组是否包含某个 item,项目中只能自己编写该方法。
刚入门时第一个想到的方法就是对某个类型的数组进行遍历,再逐个对比,但这样有个最大的问题就是我们只能对一种类型的数组进行对比,不能灵活的应对各种类型。
reflect
在 stackexchange 中看到一个方法,充分的利用了 reflect
包对 interface{}
进行判断,如下
1 | package main |
一次遍历
2019-03-21 更新:
今天才从网上看到一个说法,Go 中 reflect
很慢,尽量不要使用,我心里咯噔一下,赶紧来测试下
对比下强类型遍历的方法
1 | func StringsContains(array []string, val string) (index int) { |
使用 testing
包来测试性能
1 | import "testing" |
运行
1 | $ go test -bench=. |
结果非常明显,Contains
方法平均每次 635 ns
,StringsContains
方法平均每次 20.3 ns
嗯,我得先缓一下,为什么 reflect
这么慢呢,reflect为什么慢这篇文章给了很好的解释,总结下来有两点
- 涉及到内存分配以后GC
- reflect实现里面有大量的枚举
不管怎样,reflect
耗时长是不争的事实,又浏览了下其他的文章,大多观点都视它如“猛虎”,避之不及。
但是静下心来想想,大可不必。慢,也是相对的。毕竟这个例子很简单,为了追求性能,当然可以使用强类型比较,那如果是更复杂的映射操作呢,Go 是强类型语言啊,你不用 reflect
用啥。反射就不能用,你让 SpringMVC 咋办。
wgo
在官方完美解决这个问题前,我们只能在项目中自己写方法,或者使用第三方包 wgo
wgo 是类似 Python 交互命令的脚本化运行工具。
该包本身包含一些开发中常用但是 Go 不具备的方法和工具。
安装
1 | $ go get -u github.com/wxnacy/wgo |
导入
1 | import "github.com/wxnacy/wgo/arrays" |
常用 Contains 方法
1 | // Contains Returns the index position of the val in array |
1 | // ContainsString Returns the index position of the string val in array |
1 | // ContainsInt Returns the index position of the int64 val in array |
1 | // ContainsFloat Returns the index position of the float64 val in array |
1 | // ContainsBool Returns the index position of the bool val in array |
demo
1 | package main |