Golang实践总结(一) -- interface和类型断言、Redis和多条件查询

魔改谢馒头 · · 294 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

上一篇发布的文章应该也算是总结,也是工作中遇到的问题。现在入职新公司半个多月,.net的脑子差不多已经换成了golang。目前第一个小项目已经提测,写项目的过程中也遇到了一些小问题,在周末快下班的时候做一些总结,消化和拓展一下涉及到的知识点。

interface和类型断言

我们都知道的一点是golang并不支持泛型,但在golang中可以使用interface{}来代替泛型的功能。
在开始自己学习的时候也看到过这个知识点,有大致了解过接口可以通过泛型接收任意类型的变量,然后再在方法里用反射去赋值或者解析。
但是具体使用上会遇到很多小坑,我贴一些代码,举几个例子

func (this *RedisManager) GetValue(redisConn redis.Conn, key string, object interface{}) error {

    result, err := redis.Bytes(redisConn.Do("GET", key))

    if err != nil {
        return err
    }

    err = json.Unmarshal(result, object)

    if err != nil {

        return errors.New(fmt.Sprintf("REDIS-->JSON解码错误: %s %s", reflect.TypeOf(object), string(result)))
    }

    return nil
}

对于golang传参有了解的同学就能明白这里需要传入一个结构体指针,不能传值类型的参数。因为值类型是一个拷贝,方法内并不能改动方法外的原参数。
那么我们调用函数就应该写成这个样子

var result []*Item
err := Redismgr.GetValue(key, &result)
if err != nil {
...
}

然后我遇到的问题就是,我把这部分需要加工的重复代码又提到了一个新的方法里

func SelectFromRedis(.......,result interface{}) interface{}{
  ....
  err:=Redismgr.GetValue(key, result)
  ....
  return result
}

var result []*Item
result = SelectFromRedis(.....,&result)

好的我们来看一下,上面代码最后一行有个错误。
cannot use SelectFromRedis(.....,&result)(type interface{}) as type []*Item in assignment: need type assertion
IDE会提示你,虽然所有类型都继承了interface,但你不能直接用interface直接当成目标类型来用,你需要写断言。

可以,那按他的提示改一下

result = SelectFromRedis(.....,&result).([]*Item)

这时候IDE也不报错,满心以为程序好使了,但是运行起来以后疯狂报错。
查了半天,打了半天的log,最后发现,因为传入的是&result,传入到SelectFromRedis时的类型已经变成了*[]*Item类型,所以再用[]*Item去断言就会报错了。

对于这种问题有一个很简单的方法就是,如果你并不确定需要断言什么类型,只要把变量的类型打印出来自己看一下再写就好了

fmt.Printf("result type is :%T",result)

Redis和多条件查询

本文来自:简书

感谢作者:魔改谢馒头

查看原文:Golang实践总结(一) -- interface和类型断言、Redis和多条件查询

入群交流(和以上内容无关):Go中文网 QQ 交流群:798786647 或加微信入微信群:274768166 备注:入群;关注公众号:Go语言中文网

294 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传