我正在尝试对包含Interface {}作为字段的结构进行解析和编码.
问题在于,编码工作正常,但如果我尝试将数据解码data为值得到{ <nil>}.
它实际上是有效的,如果我Data interface{}改为Data substring,但这不是我的解决方案,因为我想将查询的结果缓存到具有不同类型的数据库,具体取决于查询.(例如Users或Cookies)
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)
}
Run Code Online (Sandbox Code Playgroud)
编码:[37 255 129 3 1 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 0 29 255 131 3 1 1 7 83 117 98 84 121 112 101 1 255 132 0 1 1 1 3 70 111 111 1 12 0 0 0 19 255 130 1 6 70 111 111 66 97 114 1 1 4 84 101 115 116 0 0]
解码:{FooBar {Test}}
编码:[37 255 129 3 1 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 0 29 255 131 3 1 1 7 83 117 98 84 121 112 101 1 255 132 0 1 1 1 3 70 111 111 1 12 0 0 0 19 255 130 1 6 70 111 111 66 97 114 1 1 4 84 101 115 116 0 0]
解码:{}
Dmi*_*yov 39
问题是在你的代码中,执行时出错,encCache.Encode(encodeData)但由于你没有检查错误,你没有意识到这一点.输出为空,因为encodedData无法正确编码.
如果添加错误检查,
err := enc.Encode(encodeData)
if err != nil {
log.Fatal("encode error:", err)
}
Run Code Online (Sandbox Code Playgroud)
然后你会看到类似的东西
2013/03/09 17:57:23 encode error:gob: type not registered for interface: main.SubType
Run Code Online (Sandbox Code Playgroud)
如果在enc.Encode(encodeData)之前向原始代码添加一行,
gob.Register(SubType{})
Run Code Online (Sandbox Code Playgroud)
然后你得到预期的输出.
Decoded: {FooBar {Test}}
Run Code Online (Sandbox Code Playgroud)
见http://play.golang.org/p/xt4zNyPZ2W
Jer*_*all -7
您无法解码为接口,因为解码器无法确定字段应该是什么类型。
您可以通过几种不同的方式来处理这个问题。一种是让 Data 保存一个结构体,其中包含可以解码的每种类型的字段。但类型可能非常复杂。
另一种方法是为您的结构实现 GobDecoder 和 GobEncoder 接口,并为类型实现您自己的序列化。但这可能并不理想。
也许最好的方法是让缓存存储特定类型,并为每种类型使用单独的方法。用你的例子。您的应用程序将有一个GetSubType(key string) (*SubType, error)在缓存上调用的缓存方法。这将返回具体类型或解码错误而不是接口。它将更干净、更具可读性并且类型更安全。
| 归档时间: |
|
| 查看次数: |
8513 次 |
| 最近记录: |