在 Golang 中实现 Cache::remember 方法详解


Posted in Python onMarch 30, 2021

项目需要把部分代码移植到 Golang , 之前用 Laravel 封装的写起来很舒服,在 Golang 里只能自动动手实现.
一开始想的是使用 interface 实现,但是遇到了一个坑, Golang 里的组合是一个虚假的继承

package main
 
import "fmt"
 
type Person interface {
 Say()
 Name()
}
 
type Parent struct {
}
 
func (s *Parent) Say() {
 fmt.Println("i am " + s.Name())
}
 
func (s *Parent) Name() string {
 return "parent"
}
 
type Child struct {
 Parent
}
 
func (s *Child) Name() string {
 return "child"
}
 
type Child1 struct {
 Parent
}
 
func main() {
 
 var c Child
 // i am parent
 c.Say()
 
 var c1 Child1
 // i am parent
 c1.Say()
}
  • 如上 c.say() 代码,在别的语言里应该是输出 i am child 才对, 而 Golang 不一样,查了一下 Golang 的资料才能理解 https://golang.org/ref/spec#Selectors
  • 大致意思是说,通过 x.f 调用 f 方法或者属性时,从当前或者嵌套匿名结构体由浅到深的去调用,而不会去寻找上级
  • 比如 child1 没有 Say 方法,会进入到匿名结构体 Parent 找到 Say 方法,然后调用
  • 而 child 也没有 Say 方法,同样去调用 Parent 的 Say 方法,这时候 Say 是通过 Parent 调用的, 当在 Say 里调用 s.Name 方法,并不能找到 child , 所以还是会调用到 Parent 的 Name 方法
  • 然后自己整理和同事一起写了大致的 remember 方法
import (
 "context"
 "encoding/json"
 "fmt"
 "github.com/gin-gonic/gin"
 "time"
)
 
// redis 操作已经简化
func CacheGet(c context.Context, t interface{}, cacheKey string, callQuery func() error) error {
 
 // 此处通过 redis 获取数据, 如果存在数据, 那么直接返回
 dataBytes, err := redis.Get(c, cacheKey).Bytes()
 if err == nil {
  if err := json.Unmarshal(dataBytes, t); err == nil {
   return nil
  }
 }
 
 // 当 redis 没有数据, 那么调用此方法修改 t,
 if err := callQuery(); err != nil {
 
  return err
 }
 
 // 这里把修改之后的 t 存储到 redis, 下次使用便可以使用缓存
 dataBytes, err = json.Marshal(t)
 if err == nil {
  redis.Set(c, cacheKey, dataBytes, time.Minute*30)
 }
 return nil
}
 
func handle(c *gin.Context) {
 
 var model models.User
 err := utils.CacheGet(
  c.Request.Context(),
  &model,
  fmt.Sprintf("cache_xxx:%s", c.Param("id")),
  func() error {
 
   return db.First(&model)
  },
 )
}

到此这篇关于在 Golang 中实现 Cache::remember 方法的文章就介绍到这了,更多相关Golang实现 Cache::remember 内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python的迭代器与生成器实例详解
Jul 16 Python
在Python的Tornado框架中实现简单的在线代理的教程
May 02 Python
Python中random模块用法实例分析
May 19 Python
Python+Pika+RabbitMQ环境部署及实现工作队列的实例教程
Jun 29 Python
详解python进行mp3格式判断
Dec 23 Python
解决pip install的时候报错timed out的问题
Jun 12 Python
Python 实现子类获取父类的类成员方法
Jan 11 Python
使用TensorFlow实现二分类的方法示例
Feb 05 Python
python pandas 时间日期的处理实现
Jul 30 Python
python函数声明和调用定义及原理详解
Dec 02 Python
Django如何在不停机的情况下创建索引
Aug 02 Python
python绘制云雨图raincloud plot
Aug 05 Python
Python离线安装openpyxl模块的步骤
解决Jupyter-notebook不弹出默认浏览器的问题
Python爬取科目四考试题库的方法实现
Python如何使用logging为Flask增加logid
Mar 30 #Python
如何在Python中创建二叉树
pycharm2021激活码使用教程(永久激活亲测可用)
python实现web邮箱扫描的示例(附源码)
You might like
在PHP中利用XML技术构造远程服务(下)
2006/10/09 PHP
十天学会php之第六天
2006/10/09 PHP
PHP管理内存函数 memory_get_usage()使用介绍
2012/09/23 PHP
php实现的ping端口函数实例
2014/11/12 PHP
php实现表单多按钮提交action的处理方法
2015/10/24 PHP
thinkphp中多表查询中防止数据重复的sql语句(必看)
2016/09/22 PHP
PHP完全二叉树定义与实现方法示例
2017/10/09 PHP
IE6 弹出Iframe层中的文本框“经常”无法获得输入焦点
2009/12/27 Javascript
放弃用你的InnerHTML来输出HTML吧 jQuery Tmpl不详细讲解
2013/04/20 Javascript
jQuery弹性滑动导航菜单实现思路及代码
2013/05/02 Javascript
跟我学习javascript的基本类型和引用类型
2015/11/16 Javascript
javascript函数中的3个高级技巧
2016/09/22 Javascript
jQuery事件与动画基础详解
2017/02/23 Javascript
vue的toast弹窗组件实例详解
2018/05/14 Javascript
Vue框架里使用Swiper的方法示例
2018/09/20 Javascript
在vue中使用echarts图表实例代码详解
2018/10/22 Javascript
vue-cli3 配置开发与测试环境详解
2019/05/17 Javascript
详解node.js 事件循环
2020/07/22 Javascript
Vue实现简单购物车功能
2020/12/13 Vue.js
python目录操作之python遍历文件夹后将结果存储为xml
2014/01/27 Python
python实现在pickling的时候压缩的方法
2014/09/25 Python
python爬取51job中hr的邮箱
2016/05/14 Python
Python获取网段内ping通IP的方法
2019/01/31 Python
python抓取需要扫微信登陆页面
2019/04/29 Python
如何用Python来搭建一个简单的推荐系统
2019/08/07 Python
Python中字典与恒等运算符的用法分析
2019/08/22 Python
python实现最大优先队列
2019/08/29 Python
Python3实现配置文件差异对比脚本
2019/11/18 Python
Tensorflow加载Vgg预训练模型操作
2020/05/26 Python
html5的localstorage详解
2017/05/09 HTML / CSS
Html5跳转到APP指定页面的实现
2020/01/14 HTML / CSS
编程实现当输入某产品代码则打印出该产品记录的功能
2014/05/03 面试题
放飞梦想演讲稿
2014/05/05 职场文书
2014年幼儿园保育工作总结
2014/12/02 职场文书
文明家庭事迹材料
2014/12/20 职场文书
信息技术教研组工作总结
2015/08/13 职场文书