指针和 protobufs 无法解释的行为

Unexplained behavior with pointers and protobufs

我正在努力找出这种行为的原因,或者这可能是假设发生的,但我只是不知道。 对于背景,我正在使用 proto3,并在 Go1.15 中执行此操作,我知道 packed 是 proto3 中的默认设置,而且我对 protobufs 比较陌生。

我在原型文件中定义了以下消息:

message Response {
    repeated uint32 points = 1 [packed=true];
}

这将使用 protoc-gen-go v1.25.0 生成以下代码。

type Response struct {
     state         protoimpl.MessageState
     sizeCache     protoimpl.SizeCache
     unknownFields protoimpl.UnknownFields

     Points []uint32 `protobuf:"varint,3,rep,packed,name=points,json=points,proto3" json:"points,omitempty"`
}

我开始使用新结构,但它的行为与我通常期望的结构不同。这是我写的一些东西,以及打印出来的东西。

newResponse := pb.Response{Points: []uint32{2,4,6,8}}
fmt.Println(newResponse)
//{{{} [] [] <nil>} 0 [] [2 4 6 8]  --> I expect this
refToNewResponse := &newResponse
fmt.Println(refToNewResponse)
// points:2  points:4  points:6  points:8 --> not what I expected

现在您可能会想,这只是格式化而已。 但我希望有一个列表……而不是每个数字都有一个标签。我已经看到并使用了其他 protobufs...当我看到它们 return 的响应时,它看起来不是这样的,它是列表的一个标签,如:

points: [2 4 6 8]

我确实需要使用这个的参考版本,因为我最终想扩展并使用一个响应列表,生成的代码会吐出一片指针响应,但我不明白为什么它要分离和标记切片中的每个元素。

我希望有人能指出我正在做或没有做的事情是造成这种情况的原因...在此先感谢您。

这确实只是格式化。底层数据结构没有任何变化。您请求了一个 repeated uint32 Points 并且它确实以这种方式打印它们。

protobuf 实现中的编组器真的可以输出任何它喜欢的东西,protobuf 的human-readable 表示没有参考版本

如果您确实必须为 .String() 输出自定义格式,您可以尝试使用不同的原型库,例如 gogoprotobuf,或尝试各种扩展。但最终,它只是 human-readable 输出。

注:

  • 这与packed=true(确实是默认值)无关。
  • 如果您对打印指针和基本类型感到困惑,那是因为 String() 方法有一个指针接收器。参见 this question