[Golang]通过interface实现"泛型"的用例

前端之家收集整理的这篇文章主要介绍了[Golang]通过interface实现"泛型"的用例前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

目前Golang最新版本为1.9,暂时不支持泛型。
不过可以通过interface实现”泛型编程”效果,下面以slice类型数据的添加/删除元素为例,
供大家参考一下:

package main

import (
    "errors"
    "fmt"
)

var (
    ERR_ELEM_EXISTS     = errors.New("element exits.")
    ERR_ELEM_NOT_EXISTS = errors.New("element not exits.")
)

// 定义切片,支持interface{}类型
// 假设该slice不支持存储相同元素
type SomeSlice []interface{}

// 初始化slice实例
func NewSomeSlice() SomeSlice {
    return make(SomeSlice, 0)
}

// 定义一个用于对比的接口
type Comparable interface {
    IsEqual(a interface{}) bool
}

// 定义struct类型
type Employee struct {
    Id   int32
    Name string
}

// Employee类型实现了Comparable接口
func (em Employee) IsEqual(b interface{}) bool {
    if em2,ok := b.(Employee); ok {
        return em.Id == em2.Id
    } else {
        return false
    }
}

// isEqual函数用于各种类型之间的比较
func isEqual(a,b interface{}) bool {
    if cmpa,ok := a.(Comparable); ok {
        return cmpa.IsEqual(b)
    } else if cmpb,ok := b.(Comparable); ok {
        return cmpb.IsEqual(a)
    } else {
        return a == b
    }
}

// 向slice添加元素
func (ss *SomeSlice) Add(elem interface{}) error {
    for _,v := range *ss {
        if isEqual(v,elem) {
            fmt.Printf("[Error]Cannot add the same element: %v\n",elem)
            return ERR_ELEM_EXISTS
        }
    }
    *ss = append(*ss,elem)
    return nil
}

//从slice中删除元素
func (ss *SomeSlice) Remove(elem interface{}) error {
    for k,elem) {
            if k == len(*ss)-1 {
                *ss = (*ss)[:k]
            } else {
                *ss = append((*ss)[:k],(*ss)[k+1:]...)
            }
            return nil
        }
    }
    fmt.Printf("[Error]No such element: %v\n",elem)
    return ERR_ELEM_NOT_EXISTS
}

func main() {
    // 初始化slice
    slice := NewSomeSlice()

    // 正常情况下添加不同类型元素
    slice.Add(5)
    slice.Add("huahua")
    slice.Add(Employee{Id: 123,Name: "xiaohong"})
    slice.Add(10)
    slice.Add("xiaoming")
    slice.Add(Employee{Id: 456,Name: "xiaogang"})
    fmt.Println("After Add,Current Slice:",slice)

    // 添加了重复的元素
    slice.Add(10)
    slice.Add("huahua")
    slice.Add(Employee{Id: 456,Name: "xiaogang"})
    fmt.Println("After invalid Add,slice)

    // 正常情况下删除元素
    slice.Remove(5)
    slice.Remove("huahua")
    slice.Remove(Employee{Id: 456,Name: "xiaogang"})
    fmt.Println("After Remove,slice)

    // 删除并不存在的元素
    slice.Remove(11)
    slice.Remove("somename")
    slice.Remove(Employee{Id: 789,Name: "dajiu"})
    fmt.Println("After invalid Remove,slice)
}

运行结果如下所示:

pintai@MG:~/src$ go run tmpl.go
After Add,Current Slice: [5 huahua {123 xiaohong} 10 xiaoming {456 xiaogang}]
[Error]Cannot add the same element: 10
[Error]Cannot add the same element: huahua
[Error]Cannot add the same element: {456 xiaogang}
After invalid Add,Current Slice: [5 huahua {123 xiaohong} 10 xiaoming {456 xiaogang}]
After Remove,Current Slice: [{123 xiaohong} 10 xiaoming]
[Error]No such element: 11
[Error]No such element: somename
[Error]No such element: {789 dajiu}
After invalid Remove,Current Slice: [{123 xiaohong} 10 xiaoming]

上面的例子实现了支持不同类型元素的slice,通过Add/Remove方法进行增删元素。
其中一个关键方法是isEqual,对于实现了Comparable类型的对象使用了它的IsEqual方法来比较,对于其他类型(基础类型)数据则直接用 == 来进行比较。

原文链接:https://www.f2er.com/go/187591.html

猜你在找的Go相关文章