分享
Golang比较两个slice是否相等(二) - 封装
Avery_up · · 1193 次点击 · · 开始浏览这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。
在前一篇文章中简单封装了int类型的Slice,并且通过基准测试得出性能远远高于 reflect.DeepEqual 。
本章将封装一个通用的包比较各种值类型的slice,在已知slice值类型时使用。
思路分析
- 定义一个 interface 名为
Interface,包含两个方法:len()返回slice的长度,item()根据索引获取值 - 定义
compare方法,接收两个实现了Interface的 slice ,进行比较。 - 定义类型
StringSlice用于比较string类型;IntSlice用于比较int类型;int64、float64、float32 等类似。
实现示例
新建文件: path/compare/slice.go,以 string 和 int 类型为例,实现封装。
package compare
type Interface interface {
// len方法返回集合中的元素个数
Len() int
// item方法根据索引返回集合的值
Item(idx int) interface{}
}
type IntSlice []int
func (p IntSlice) Len() int { return len(p) }
func (p IntSlice) Item(idx int) interface{} { return p[idx] }
func Ints(a, b []int) bool {
return Compare(IntSlice(a), IntSlice(b))
}
type StringSlice []string
func (p StringSlice) Len() int { return len(p) }
func (p StringSlice) Item(idx int) interface{} { return p[idx] }
func Strings(a, b []string) bool {
return Compare(StringSlice(a), StringSlice(b))
}
// compare 循环遍历比较两个集合
// 先比较两个集合的长度是否相等
// 再循环遍历每一个元素进行比较
func Compare(a, b Interface) bool {
if a.Len() != b.Len() {
return false
}
if (a == nil) != (b == nil) {
return false
}
for i := 0; i < a.Len(); i++ {
if a.Item(i) != b.Item(i) {
return false
}
}
return true
}
调用示例
package main
import (
"./compare"
"fmt"
)
func main() {
s1 := []string{"h", "e", "l", "l", "o"}
s2 := []string{"h", "e", "l", "l", "o"}
if compare.Strings(s1, s2) {
fmt.Println("equal..") // equal...
} else {
fmt.Println("not equal!")
}
}
性能测试
新建文件: path/compare/slice_test.go
package compare
import (
"reflect"
"testing"
)
var (
slice1 = []string{"foo", "bar", "h", "e", "l", "l", "o"}
slice2 = []string{"foo", "bar", "h", "e", "l", "l", "oooo"}
)
func BenchmarkStrings(b *testing.B) {
for i := 0; i < b.N; i++ {
Strings(slice1, slice2)
}
}
func BenchmarkRelfectDeepEqual(b *testing.B) {
for i := 0; i < b.N; i++ {
reflect.DeepEqual(slice1, slice2)
}
}
Benchmark测试结果:
BenchmarkStrings-4 2000000 705 ns/op
BenchmarkRelfectDeepEqual-4 1000000 1254 ns/op
使用包
代码已封装推送到github,在项目中可以直接使用。
拉取项目代码
go get -u -v github.com/gushasha/go-learn
使用示例
package main
import (
"fmt"
"github.com/gushasha/go-learn/compare"
)
func main() {
s1 := []string{"h", "e", "l", "l", "o"}
s2 := []string{"h", "e", "l", "l", "o"}
if compare.Strings(s1, s2) {
fmt.Println("equal..")
} else {
fmt.Println("not equal!")
}
}
查看github源码
有疑问加站长微信联系(非本文作者)
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信1193 次点击
上一篇:golang比较浮点数是否相等
下一篇:事件驱动的微服务-总体设计
添加一条新回复
(您需要 后才能回复 没有账号 ?)
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传
收入到我管理的专栏 新建专栏
在前一篇文章中简单封装了int类型的Slice,并且通过基准测试得出性能远远高于 reflect.DeepEqual 。
本章将封装一个通用的包比较各种值类型的slice,在已知slice值类型时使用。
思路分析
- 定义一个 interface 名为
Interface,包含两个方法:len()返回slice的长度,item()根据索引获取值 - 定义
compare方法,接收两个实现了Interface的 slice ,进行比较。 - 定义类型
StringSlice用于比较string类型;IntSlice用于比较int类型;int64、float64、float32 等类似。
实现示例
新建文件: path/compare/slice.go,以 string 和 int 类型为例,实现封装。
package compare
type Interface interface {
// len方法返回集合中的元素个数
Len() int
// item方法根据索引返回集合的值
Item(idx int) interface{}
}
type IntSlice []int
func (p IntSlice) Len() int { return len(p) }
func (p IntSlice) Item(idx int) interface{} { return p[idx] }
func Ints(a, b []int) bool {
return Compare(IntSlice(a), IntSlice(b))
}
type StringSlice []string
func (p StringSlice) Len() int { return len(p) }
func (p StringSlice) Item(idx int) interface{} { return p[idx] }
func Strings(a, b []string) bool {
return Compare(StringSlice(a), StringSlice(b))
}
// compare 循环遍历比较两个集合
// 先比较两个集合的长度是否相等
// 再循环遍历每一个元素进行比较
func Compare(a, b Interface) bool {
if a.Len() != b.Len() {
return false
}
if (a == nil) != (b == nil) {
return false
}
for i := 0; i < a.Len(); i++ {
if a.Item(i) != b.Item(i) {
return false
}
}
return true
}
调用示例
package main
import (
"./compare"
"fmt"
)
func main() {
s1 := []string{"h", "e", "l", "l", "o"}
s2 := []string{"h", "e", "l", "l", "o"}
if compare.Strings(s1, s2) {
fmt.Println("equal..") // equal...
} else {
fmt.Println("not equal!")
}
}
性能测试
新建文件: path/compare/slice_test.go
package compare
import (
"reflect"
"testing"
)
var (
slice1 = []string{"foo", "bar", "h", "e", "l", "l", "o"}
slice2 = []string{"foo", "bar", "h", "e", "l", "l", "oooo"}
)
func BenchmarkStrings(b *testing.B) {
for i := 0; i < b.N; i++ {
Strings(slice1, slice2)
}
}
func BenchmarkRelfectDeepEqual(b *testing.B) {
for i := 0; i < b.N; i++ {
reflect.DeepEqual(slice1, slice2)
}
}
Benchmark测试结果:
BenchmarkStrings-4 2000000 705 ns/op
BenchmarkRelfectDeepEqual-4 1000000 1254 ns/op
使用包
代码已封装推送到github,在项目中可以直接使用。
拉取项目代码
go get -u -v github.com/gushasha/go-learn
使用示例
package main
import (
"fmt"
"github.com/gushasha/go-learn/compare"
)
func main() {
s1 := []string{"h", "e", "l", "l", "o"}
s2 := []string{"h", "e", "l", "l", "o"}
if compare.Strings(s1, s2) {
fmt.Println("equal..")
} else {
fmt.Println("not equal!")
}
}