美文网首页
关于go泛型萃取简记

关于go泛型萃取简记

作者: hijiang | 来源:发表于2019-06-16 18:12 被阅读0次

    最近由于代码需要,需要在一个map中存泛型,例如:

    var data map[string] interface{} = make(map[string]interface{})
    

    然后通过关键字索引查询得到map对应key,大致方法是:

    func Get(name string, pval interface{}) error
    

    当然,上面的pval传入的是指针,这样才能正确将值设置到pval指针中并返回给上层。
    在C++中,经常也有类似的需求,但是C++由于有比较清晰的继承,所以在C++代码中使用泛型可以很容易处理这种需求,在这里不再赘述。

    所以在考虑如何优雅的实现上述接口函数,于是翻阅了下golang的reflect,使用映射,可以完美实现,这种方法可以推广到很多其他形式,来处理go的泛型化,使代码更加优雅。
    实现及注释代码如下:

    var m map[string]interface{}
    
    func Get(name string, pval interface{}) error {
        //先判断是否传入的指针
        if reflect.TypeOf(pval).Kind() != reflect.Ptr {
            return errors.New("pval is not a ptr")
        }
    
        for k, v := range m {
            if k == name {
                //判断类型是否一致
                if reflect.TypeOf(pval).Elem() == reflect.TypeOf(v) {
                    //获取Ptr元素值,并Set
                    reflect.ValueOf(pval).Elem().Set(reflect.ValueOf(v))
                    return nil
                } else {
                    return errors.New("value type not equal")
                }
            }
        }
        return errors.New("not find the key" + name)
    }
    
    

    测试代码如下:

    package main
    
    import (
        "errors"
        "fmt"
        "reflect"
    )
    
    type Human struct {
        name string
        age  int32
    }
    
    var m map[string]interface{}
    
    func Get(name string, pval interface{}) error {
        //先判断是否传入的指针
        if reflect.TypeOf(pval).Kind() != reflect.Ptr {
            return errors.New("pval is not a ptr")
        }
    
        for k, v := range m {
            if k == name {
                //判断类型是否一致
                if reflect.TypeOf(pval).Elem() == reflect.TypeOf(v) {
                    //获取Ptr元素值,并Set
                    reflect.ValueOf(pval).Elem().Set(reflect.ValueOf(v))
                    return nil
                } else {
                    return errors.New("value type not equal")
                }
            }
        }
        return errors.New("not find the key" + name)
    }
    
    func main() {
        m = make(map[string]interface{})
        m["aaa"] = "abc"
        m["bbb"] = 123
        m["xiaoming"] = Human{name: "xiaoming", age: 32}
        _ = m
        var val Human
        Get("xiaoming", &val)
        fmt.Println("val=", val)
    }
    

    打印结果如下:

    Get xiaoming= {xiaoming 32}
    value type not equal
    

    第二行的错误,是因为类型不匹配,所以没有问题,虽然之前也用过reflect,但是有时候还是记不住,只是看文档时才知道原来这样,写下来比较好
    github:https://github.com/jbl19860422/test_extract

    相关文章

      网友评论

          本文标题:关于go泛型萃取简记

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