开发学院

您的位置:首页>教程>正文

教程正文

Protocol Buffer Go实例教程:读写消息

写信息

  使用Protocol Buffer的目的是序列化您的数据,以便可以在其他地方对其进行解析。在Go中,您使用proto库的Marshal函数来序列化Protocol Buffer数据。指向Protocol Buffer消息结构的指针实现了proto.Message接口。调用proto.Marshal返回以有线格式编码的protocol buffer。例如,我们在add_person命令中使用这个函数:

book := &pb.AddressBook{}
// ...

// Write the new address book back to disk.
out, err := proto.Marshal(book)
if err != nil {
        log.Fatalln("Failed to encode address book:", err)
}
if err := ioutil.WriteFile(fname, out, 0644); err != nil {
        log.Fatalln("Failed to write address book:", err)
}

读消息

  要解析编码的消息,可以使用proto库的Unmarshal函数。调用此命令会将buf中的数据解析为protocol buffer,并将结果放入pb中。因此,为了解析list_people命令中的文件,我们使用:

// Read the existing address book.
in, err := ioutil.ReadFile(fname)
if err != nil {
        log.Fatalln("Error reading file:", err)
}
book := &pb.AddressBook{}
if err := proto.Unmarshal(in, book); err != nil {
        log.Fatalln("Failed to parse address book:", err)
}

扩展Protocol Buffer

  在您发布使用protocol buffer的代码后,您迟早会毫无疑问地想要“改进”protocol buffer的定义。如果你想让你的新protocol buffer向后兼容,让你的旧protocol buffer向前兼容,那么你需要遵守一些规则,在新版本的protocol buffer中:

  •   您不能更改任何现有字段的标签号。

  •   您可以删除字段。

  •   您可以添加新字段,但必须使用新的标签号(即,从未在此protocol buffer中使用过的标签号,甚至未被删除的字段使用过)。

  (这些规则有一些例外,但很少使用)

  如果您遵循这些规则,旧代码将愉快地阅读新消息,并简单地忽略任何新字段。对于旧代码,被删除的单个字段将只具有它们的默认值,被删除的重复字段将为空。新代码也会透明地读取旧消息。

  但是,请记住,新字段不会出现在旧消息中,因此您需要用默认值做一些合理的事情。使用特定类型的默认值:对于字符串,默认值是空字符串。对于布尔值,默认值为false。对于数值类型,默认值为零。