美文网首页
Golang比较两个slice是否相等(二) - 封装

Golang比较两个slice是否相等(二) - 封装

作者: Avery_up | 来源:发表于2020-04-14 17:36 被阅读0次

    前一篇文章中简单封装了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源码

    相关文章

      网友评论

          本文标题:Golang比较两个slice是否相等(二) - 封装

          本文链接:https://www.haomeiwen.com/subject/vpwtvhtx.html