英文:
What is Marshal and unmarshal in Golang Proto?
问题
我理解我们需要使用marshal函数将对象序列化,使用unmarshal函数将其反序列化。然而,我的问题是,我们何时调用marshal和unmarshal函数,以及为什么在不久后又要对对象进行反序列化。
PS:我刚开始学习Go和Proto,非常感谢你的帮助。谢谢。
英文:
I understand that we need to marshall object to serialise it, and unMarshall to deserialise it. However my question is, when do we invoke marshal and unmarshal and why do we serialise the objects if we are going to deserialise it again soon?
PS I just started to learn Go and Proto so would really appreciate your help. Thank you.
答案1
得分: 8
很好的问题!
编组(也称为序列化)将结构体转换为原始字节。通常,在将数据发送到程序外部时会这样做:你可能会将其写入文件或将结构体发送到HTTP请求体中。
解组(也称为反序列化)将原始字节转换为结构体。当接受来自程序外部的数据时,你会这样做:你可能会从文件或HTTP响应体中读取数据。
在这两种情况下,发送数据的程序将其作为结构体存储在内存中。我们需要进行编组和解组,因为接收方程序无法直接访问发送方的内存并读取结构体。为什么呢?
- 通常,这两个程序位于不同的计算机上,因此无法直接访问彼此的内存。
- 即使是在同一台计算机上的两个进程,共享内存也是复杂且通常危险的。如果在另一个程序读取数据时,你正在进行数据覆盖的一半怎么办?如果你的结构体包含敏感数据(如解密后的密码)会发生什么?
- 即使共享内存,这两个程序也需要以相同的方式解释数据。不同的编程语言,甚至不同版本的Go,在内存中以不同的方式表示相同的结构体。例如,你是以最高有效位优先还是最低有效位优先表示整数?根据他们的答案,一个程序可能会将
001
解释为整数1
,而另一个程序可能会将相同的内存解释为整数4
。
如今,我们通常将编组和解组到一些标准化格式,如JSON、CSV或YAML。 (在过去,情况并非总是如此-你经常会手动将结构体转换为字节,使用在当时有意义的任何逻辑。)Protobuf模式使得更容易生成编组和解组代码,这些代码在CPU和空间效率(与CSV或JSON相比)、强类型和跨编程语言之间的一致性方面工作。
英文:
Good question!
Marshaling (also called serializing) converts a struct to raw bytes. Usually, you do this when you're sending data to something outside your program: you might be writing to a file or sending the struct in an HTTP request body.
Unmarshaling (also called deserializing) converts raw bytes to a struct. You do this when you're accepting data from outside your program: you might be reading from a file or an HTTP response body.
In both situations, the program sending the data has it in memory as a struct. We have to marshal and unmarshal because the recipient program can't just reach into the sender's memory and read the struct. Why?
- Often the two programs are on different computers, so they can't access each other's memory directly.
- Even for two processes on the same computer, shared memory is complex and usually dangerous. What happens if you're halfway through overwriting the data when the other program reads it? What if your struct includes sensitive data (like a decrypted password)?
- Even if you share memory, the two programs need to interpret the data in the same way. Different languages, and even different versions of Go, represent the same struct differently in memory. For example, do you represent integers with the most-significant bit first or last? Depending on their answers, one program might interpret
001
as the integer1
, while the other might interpret the same memory as the integer4
.
Nowadays, we're usually marshaling to and unmarshaling from some standardized format, like JSON, CSV, or YAML. (Back in the day, this wasn't always true - you'd often convert your struct to and from bytes by hand, using whatever logic made sense to you at the time.) Protobuf schemas make it easier to generate marshaling and unmarshaling code that's CPU- and space-efficient (compared to CSV or JSON), strongly typed, and works consistently across programming languages.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论