我正在try 对一个包含Interface{}As字段的 struct 进行解码和编码.

问题是,编码工作得很好,但如果我try 将数据解码为data,则值会变为{ <nil>}.

如果我将Data interface{}更改为Data substring,它实际上是有效的,但这对我来说不是一个解决方案,因为我想将查询结果缓存到一个数据库,该数据库的类型取决于查询的不同.(例如UsersCookies)

Minimal working example

来源

http://play.golang.org/p/aX7MIfqrWl

package main

import (
    "bytes"
    "encoding/gob"
    "fmt"
)

type Data struct {
    Name string
    Data interface{}
}

type SubType struct {
    Foo string
}

func main() {
    // Encode
    encodeData := Data{
        Name: "FooBar",
        Data: SubType{Foo: "Test"},
    }
    mCache := new(bytes.Buffer)
    encCache := gob.NewEncoder(mCache)
    encCache.Encode(encodeData)

    fmt.Printf("Encoded: ")
    fmt.Println(mCache.Bytes())

    // Decode
    var data Data
    pCache := bytes.NewBuffer(mCache.Bytes())
    decCache := gob.NewDecoder(pCache)
    decCache.Decode(&data)

    fmt.Printf("Decoded: ")
    fmt.Println(data)
}

输出

预期yields

编码:[37 255 129 3 1 4 68 97 116 97 1 255 130 0 1 2 1 4 78 97 109 101 1 12 0 1 4 68 97 116 97 1 255 132 0 0 29 255 131 3 1 1 7 83 117 98 84 121 101 1 255 132 0 1 1 1 3 70 111 1 12 0 0 0 19 255 130 1 6 70 111 66 97 114 1 4 101 116 0]

解码:{FooBar{Test}}

当前结果

编码:[37 255 129 3 1 4 68 97 116 97 1 255 130 0 1 2 1 4 78 97 109 101 1 12 0 1 4 68 97 116 97 1 255 132 0 0 29 255 131 3 1 1 7 83 117 98 84 121 101 1 255 132 0 1 1 1 3 70 111 1 12 0 0 0 19 255 130 1 6 70 111 66 97 114 1 4 101 116 0]

已解码:{}

推荐答案

您不能解码到接口中,因为解码器无法确定字段应该是什么类型.

你可以用几种不同的方法来处理这个问题.一种方法是让数据保存一个 struct ,每个可以解码的类型都有一个字段.但类型可能非常复杂.

另一种方法是实现 struct 的GobDecoder和GobEncoding接口,并实现您自己的类型序列化.不过,这可能并不理想.

也许最好的方法是让缓存存储特定的类型,并对每种类型使用单独的方法.用你的例子.您的应用程序在缓存上将有一个名为GetSubType(key string) (*SubType, error)的缓存方法.这将返回具体类型或解码错误,而不是接口.它会更干净、更具可读性,而且类型更安全.

Go相关问答推荐

Golang读写更接近于io.File

如何从google.golang.org/grpc/stats包中将golang中不同事件的输出进行组合,以获取func HandlePRC

读取JSON数据并在网页上显示

如何在gofr发起的服务间调用请求中添加Authorization Header?

MaybeReadByte对通道的使用如何在Go中提供随机行为?

为什么没有正确生成这些元组?

关于如何使用 Service Weaver 设置多个不同侦听器的问题

go-jwt 令牌验证错误 - 令牌签名无效:密钥类型无效

使用Dockertest进行Golang SQL单元测试的基本设置

Golang和Gin web框架在router.Run()之后执行代码

使用Cookie身份验证的Gorilla Golang Websocket优化

具有嵌套重复的正则表达式

如何在模板中传递和访问 struct 片段和 struct

Go泛型:无效的复合文字

具有两个或多个模型的 GORM 查询

Golang Gin 绑定请求正文 XML 到 Slice

golang jwt.MapClaims 获取用户ID

Golang - 使用正则表达式提取链接

从另一个没有重复的确定性 int

comparable和any有什么区别?