网络编程
位置:首页>> 网络编程>> Go语言>> 在 Golang 中实现 Cache::remember 方法详解

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

作者:施国鹏的博客  发布时间:2024-04-26 17:21:08 

标签:Golang,Cache::remember

项目需要把部分代码移植到 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)
 },
)
}

来源:https://www.shiguopeng.cn/archives/499

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com