在 BigCache 中存储任意类型(interface{})


当前第2页 返回上一页

我强烈建议您阅读 Rob Pike 写的关于 Gob 的 博客文章,这是一篇好文章。简而言之,Gob 是一种 Go 原生的数据序列化方式,它还具有序列化 interface 类型的功能。为此,您需要在序列化之前使用恰当命名的 register funtion 注册您的类型。我在这里卡住了,因为我找到的关于 register() 的任何代码示例总是注册一个单一的 struct 或 interface;我需要注册任意 interface{} 类型。我在 Go playground 上摸索了一下,发现它也可以做到。

// 大多数示例中注册的类型
type foo struct {
    bar string
}

gob.register(foo{})

// 我想要注册的类型
var type interface{} // 可以是任何结构

gob.register(type)

把它们组合在一起

解决了将任意 struct 存储为 bytes 的问题后,我将向您展示如何将它们组合在一起。首先,我们需要一个缓存 interface,以便系统的其余部分能够与之交互。对于一个简单的缓存,我们只需要 get 和 set 方法。

type Cache interface {
    Set(key, value interface{}) error
    Get(key interface{}) (interface{}, error)
}

现在,让我们定义实现上述接口的 BigCache 实现。首先,我们需要一个结构来保存缓存并可以向其中添加方法。 您还可以在此结构中添加其他字段,例如 metrics。

type bigCache struct {
    cache *bigcache.BigCache
}

接下来是 get 和 set 方法的实现。两种方法都断言 key 是 string。由此开始,get 和 set 的实现就彼此独立了。一个序列化一个值并存储它。另一个获取值并将其反序列化。

func (c *bigCache) Set(key, value interface{}) error {
    // 断言 key 为 string 类型
    keyString, ok := key.(string)
    if !ok {
        return errors.New("a cache key must be a string")
    }

    // 将 value 序列化为 bytes
    valueBytes, err := serialize(value)
    if err != nil {
        return err
    }

    return c.cache.Set(keyString, valueBytes)
}

func (c *bigCache) Get(key interface{}) (interface{}, error) {
    // 断言 key 为 string 类型
    keyString, ok := key.(string)
    if !ok {
        return nil, errors.New("a cache key must be a string")
    }

    // 获取以 bytes 格式存储的 value
    valueBytes, err := c.cache.Get(keyString)
    if err != nil {
        return nil, err
    }

    // 反序列化 valueBytes
    value, err := deserialize(valueBytes)
    if err != nil {
        return nil, err
    }

    return value, nil
}

最后是 encoding/gob 序列化逻辑。除了使用 register() 之外,这是 Go 中序列化内容相当标准的用法。

func serialize(value interface{}) ([]byte, error) {
    buf := bytes.Buffer{}
    enc := gob.NewEncoder(&buf)
    gob.Register(value)

    err := enc.Encode(&value)
    if err != nil {
        return nil, err
    }

    return buf.Bytes(), nil
}

func deserialize(valueBytes []byte) (interface{}, error) {
    var value interface{}
    buf := bytes.NewBuffer(valueBytes)
    dec := gob.NewDecoder(buf)

    err := dec.Decode(&value)
    if err != nil {
        return nil, err
    }

    return value, nil
}

通过这些,我们已经设法在 BigCache 中存储 interface{} 值了。现在我的团队的服务效率提高了一些。太酷了!如果您正在寻找一个更全面的实现,请查看我的 gist。

如果您喜欢这篇文章,请查看我的 博客 以获取类似内容。


via: https://dev.to/calebschoepp/storing-empty-interfaces-in-bigcache-1b33

作者:calebschoepp  译者:alandtsang  校对:polaris1119

本文由 GCTT 原创编译,Go语言中文网 荣誉推出


返回前面的内容

相关阅读 >>

教你使用Golang和lua实现一个值班机器人

chaos-mesh on mips64

Golang使用指针修改数据引起的血案

Golang会代替java吗?

Go语言函数闭包

Golang开发时如何debug

使用 Goroutine 和 chanel 快速实现并发和排队

Golang无法导包怎么办?

Golang如何对excel进行处理

Golang的内存管理(中篇)

更多相关阅读请进入《Go》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...