加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2020-12-16 09:41:43 所属栏目:大数据 来源:网络整理
导读:目前Golang最新版本为1.9,暂时不支持泛型。 不过可以通过interface实现”泛型编程”效果,下面以slice类型数据的添加/删除元素为例, 供大家参考一下: package main import ( "errors" "fmt" ) var ( ERR_ELEM_EXISTS = errors.New( "element exits." ) ERR_

目前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: %vn",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: %vn",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方法来比较,对于其他类型(基础类型)数据则直接用 == 来进行比较。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读