在 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中集合类型(set)学习小结
Jan 28 Python
python访问系统环境变量的方法
Apr 29 Python
在Python下进行UDP网络编程的教程
Apr 29 Python
详细解读Python的web.py框架下的application.py模块
May 02 Python
python定时检查某个进程是否已经关闭的方法
May 20 Python
Python基于回溯法子集树模板解决野人与传教士问题示例
Sep 11 Python
Python有序查找算法之二分法实例分析
Dec 11 Python
Selenium定时刷新网页的实现代码
Oct 31 Python
python 实现视频 图像帧提取
Dec 10 Python
python numpy生成等差数列、等比数列的实例
Feb 25 Python
Windows 下python3.8环境安装教程图文详解
Mar 11 Python
Python预测分词的实现
Jun 18 Python
Python离线安装openpyxl模块的步骤
解决Jupyter-notebook不弹出默认浏览器的问题
Python爬取科目四考试题库的方法实现
Python如何使用logging为Flask增加logid
Mar 30 #Python
如何在Python中创建二叉树
pycharm2021激活码使用教程(永久激活亲测可用)
python实现web邮箱扫描的示例(附源码)
You might like
千呼万唤始出来,DOTA2勇士令状不朽宝藏Ⅱ现已推出
2020/08/25 DOTA
Smarty局部缓存的几种方法简介
2014/06/17 PHP
ThinkPHP框架实现定时执行任务的两种方法分析
2018/09/04 PHP
php 使用ActiveMQ发送消息,与处理消息操作示例
2020/02/23 PHP
JQuery 将元素显示在屏幕的中央的代码
2010/02/27 Javascript
面向对象的Javascript之二(接口实现介绍)
2012/01/27 Javascript
js正文内容高亮效果的实现方法
2013/06/30 Javascript
jQuery截取指定长度字符串代码
2014/08/21 Javascript
深入理解JavaScript系列(44):设计模式之桥接模式详解
2015/03/04 Javascript
Nodejs如何搭建Web服务器
2016/03/28 NodeJs
Angular设置title信息解决SEO方面存在问题
2016/08/19 Javascript
深入浅析JS Function()构造函数
2016/08/22 Javascript
浅析BootStrap Treeview的简单使用
2016/10/12 Javascript
jQuery实现获取h1-h6标题元素值的方法
2017/03/06 Javascript
js嵌套的数组扁平化:将多维数组变成一维数组以及push()与concat()区别的讲解
2019/01/19 Javascript
JS字符串常用操作方法实例小结
2019/06/24 Javascript
一看就会的vuex实现登录验证(附案例)
2020/01/09 Javascript
在Vue中使用antv的示例代码
2020/06/29 Javascript
Python列表list数组array用法实例解析
2014/10/28 Python
Python三种遍历文件目录的方法实例代码
2018/01/19 Python
Python 3.7新功能之dataclass装饰器详解
2018/04/21 Python
Python整数对象实现原理详解
2019/07/01 Python
python飞机大战pygame游戏框架搭建操作详解
2019/12/17 Python
tensorflow实现对张量数据的切片操作方式
2020/01/19 Python
Python操作MongoDb数据库流程详解
2020/03/05 Python
解决python对齐错误的方法
2020/07/16 Python
用CSS3实现背景渐变的方法
2015/07/14 HTML / CSS
阿拉伯世界最大的电子卖场:Souq埃及
2016/08/01 全球购物
东南亚排名第一的服务市场:kaodim
2019/03/28 全球购物
红领巾广播站广播稿
2014/02/01 职场文书
母婴店促销方案
2014/03/05 职场文书
2015年世界粮食日演讲稿
2015/03/20 职场文书
休假证明书
2015/06/24 职场文书
小学英语听课心得体会
2016/01/14 职场文书
Oracle删除归档日志及添加定时任务
2022/06/28 Oracle
SpringBoot详解整合Redis缓存方法
2022/07/15 Java/Android