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

上一篇发布的文章应该也算是总结,也是工作中遇到的问题。现在入职新公司半个多月,.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和多条件查询

页面是一个多条件筛选还附带日期的一个表格,还有一个图标,后台涉及大量的判断和数据的SUM,GROUP BY,COUNT,SORT操作。平时一次查询大概需要2秒钟,再加上翻页和sort的频繁请求,会对mysql造成不小压力,而且用户体验也很不好。那么这种时候就需要redis去缓存数据,增加效率。

在设计存储结构的时候持久拿不定注意。因为筛选条件太多,需要存条件再存值的话,觉得用ZSET也好,用LIST也可以。想了半天也没有一个很好的办法,最后还是征求了一下大佬的意见。

大佬告诉我说,其实redis在设计的时候,并不需要太过严谨的储存方式,并不需要考虑数据去怎么关联。最核心的思想就是HIT OR MISS,也就是说你需要考虑的只有一个不会重复的键。(听起来像废话)

那么接下来的事情就很简单了,MD5是一个单向,不会重复的加密方式。什么意思呢,就是说我如果输入条件不变的话,最后加密出来的字符串就不会变。而之所以说他单向是因为我除非知道输入条件,是无法通过结果值来反推输入值的。

那么我在存redis的key值时候,完全可以采用 Function Name —— MD5(Request Param)的方式,直接用string类型就可以解决问题了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 对象的创建与销毁 Item 1: 使用static工厂方法,而不是构造函数创建对象:仅仅是创建对象的方法,并非Fa...
    孙小磊阅读 2,186评论 0 3
  • Chapter 6 Enums and Annotations 枚举和注解 JAVA supports two s...
    LaMole阅读 1,010评论 0 2
  • 房间里曾一直挂着那两张明信片,一张是你的宁波,有好看的林荫道,还有一张则是我从你送我的那盒明信片里找出来的唯一一张...
    他年少的时候阅读 274评论 0 4
  • 我给你的备注是十二,朋友十二画,恋人十二画,爱人十二画,家人十二画。所以,十二的名字,叫做难忘。后来想想算了吧,还...
    Crush_ade9阅读 218评论 0 0
  • 终于,终于是可以说声再见的时候了,在这永无休止的机器轰鸣声中,彻彻底底熬过两个年头,似乎找不到安静的概念,从生...
    天涯龙客阅读 175评论 0 0

友情链接更多精彩内容