项目需要把部分代码移植到 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 内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!