英文:
Generic function to store Go Encoded Data
问题
我需要编写一个通用函数,可以将对象存储为gobjects。
func hash_store(data interface{}) {
// 初始化一个 *bytes.Buffer
m := new(bytes.Buffer)
// *bytes.Buffer 满足 io.Writer 接口,可以在 gob.NewEncoder() 中使用
enc := gob.NewEncoder(m)
// gob.Encoder 有一个 Encode 方法,接受数据项作为参数
enc.Encode(data)
// bytes.Buffer 类型有一个 Bytes() 方法,返回类型为 []byte,可以作为 ioutil.WriteFile() 的参数
err := ioutil.WriteFile("dep_data", m.Bytes(), 0600)
if err != nil {
panic(err)
}
fmt.Printf("刚刚保存了所有的 depinfo:%v\n", data)
n, err := ioutil.ReadFile("dep_data")
if err != nil {
fmt.Printf("无法读取文件")
panic(err)
}
// 使用 n,类型为 []byte,创建一个 bytes.Buffer 类型
p := bytes.NewBuffer(n)
// bytes.Buffer 满足 io.Writer 接口,可以在 gob.NewDecoder() 中使用
dec := gob.NewDecoder(p)
// 创建一个我们将用解码的 gob 填充的 map 引用类型
e := make(map[string]string)
// 我们必须解码到一个指针中,所以我们将 e 的地址传递进去
err = dec.Decode(&e)
if err != nil {
fmt.Printf("无法解码")
panic(err)
}
fmt.Println("读取 dep_data 后打印:", e)
}
在这个函数中,我知道要存储在 map[string]string
中的数据类型。但是我需要编写一个通用函数,在不知道数据类型的情况下将其存储为 gobject 文件。
英文:
I need to write a generic function which can store objects as gobjects.
func hash_store(data map[string]string) {
//initialize a *bytes.Buffer
m := new(bytes.Buffer)
//the *bytes.Buffer satisfies the io.Writer interface and can
//be used in gob.NewEncoder()
enc := gob.NewEncoder(m)
//gob.Encoder has method Encode that accepts data items as parameter
enc.Encode(data)
//the bytes.Buffer type has method Bytes() that returns type []byte,
//and can be used as a parameter in ioutil.WriteFile()
err := ioutil.WriteFile("dep_data", m.Bytes(), 0600)
if err != nil {
panic(err)
}
fmt.Printf("just saved all depinfo with %v\n", data)
n,err := ioutil.ReadFile("dep_data")
if err != nil {
fmt.Printf("cannot read file")
panic(err)
}
//create a bytes.Buffer type with n, type []byte
p := bytes.NewBuffer(n)
//bytes.Buffer satisfies the interface for io.Writer and can be used
//in gob.NewDecoder()
dec := gob.NewDecoder(p)
//make a map reference type that we'll populate with the decoded gob
//e := make(map[int]string)
e := make(map[string]string)
//we must decode into a pointer, so we'll take the address of e
err = dec.Decode(&e)
if err != nil {
fmt.Printf("cannot decode")
panic(err)
}
fmt.Println("after reading dep_data printing ",e)
}
In this function I know the data type to be stored in map[string]string . But I need to write a generic function where I don't know data type and still store it as a gobject in a file.
答案1
得分: 4
将你的具体类型(map[string]string
)更改为空接口类型(interface{}
)。
参见这个相关问题,了解为什么这样做。
编码:
func store(data interface{}) {
m := new(bytes.Buffer)
enc := gob.NewEncoder(m)
err := enc.Encode(data)
if err != nil { panic(err) }
err = ioutil.WriteFile("dep_data", m.Bytes(), 0600)
if err != nil { panic(err) }
}
解码:
func load(e interface{}) {
n,err := ioutil.ReadFile("dep_data")
if err != nil { panic(err) }
p := bytes.NewBuffer(n)
dec := gob.NewDecoder(p)
err = dec.Decode(e)
if err != nil { panic(err) }
}
你在load
中放入的值必须是使用gob存储在文件中的类型的指针。
map[string]string
的示例:
org := map[string]string{"foo": "bar"}
store(org)
var loadedMap map[string]string
load(&loadedMap)
fmt.Println(loadedMap["foo"]) // bar
英文:
Change your concrete type (map[string]string
) to the empty interface type (interface{}
).
See this related question why this works.
Encoding:
func store(data interface{}) {
m := new(bytes.Buffer)
enc := gob.NewEncoder(m)
err := enc.Encode(data)
if err != nil { panic(err) }
err = ioutil.WriteFile("dep_data", m.Bytes(), 0600)
if err != nil { panic(err) }
}
Decoding:
func load(e interface{}) {
n,err := ioutil.ReadFile("dep_data")
if err != nil { panic(err) }
p := bytes.NewBuffer(n)
dec := gob.NewDecoder(p)
err = dec.Decode(e)
if err != nil { panic(err) }
}
The value you put in load
must be a pointer of the type you stored in the file using gob.
Example for map[string]string
:
org := map[string]string{"foo": "bar"}
store(org)
var loadedMap map[string]string
load(&loadedMap)
fmt.Println(loadedMap["foo"]) // bar
答案2
得分: 0
当你对数据进行编码时,给编码器一个 *interface{},然后你可以使用 *interface{} 进行解码。
var to_enc interface{} = ...;
god.NewEncoder(...).Encode(&to_enc);
...
var to_dec interface{}
god.NewDecoder(...).Decode(&to_dec);
英文:
When you encode the data, give the Encoder a *interface{}, then you can decoded with a *interface{}
var to_enc interface{} = ...;
god.NewEncoder(...).Encode(&to_enc);
...
var to_dec interface{}
god.NewDecoder(...).Decode(&to_dec);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论