英文:
Why has methods are not generated using protoc 3.17.* if in protobuf repo they say it should?
问题
阅读这里:https://github.com/protocolbuffers/protobuf/blob/master/docs/field_presence.md#go-example 中的Golang示例:
m := GetProto()
if (m.HasFoo()) {
// Clear the field:
m.Foo = nil
} else {
// Field is not present, so set it.
m.Foo = proto.Int32(1);
}
如果我使用:
protoc pkg/user.proto --go_out=. --go_opt=module=my_app --go-grpc_out=. --go-grpc_opt=module=my_app
和:
syntax = "proto3";
package example;
message MyPlayer {
uint64 id = 1;
optional string description = 2;
uint32 qty = 3;
optional uint64 age = 4;
}
它不会生成任何has<T>()
方法。
为什么?
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.17.3
如果我使用生成的MyPlayer
proto字段而不是方法,我错了吗?
例如:
if MyPlayer.description != nil {
description = *MyPlayer.description
}
而不是
description = MyPlayer.GetDescription()
这不是我想要的(我想要检测nil值)。
英文:
Reading here: https://github.com/protocolbuffers/protobuf/blob/master/docs/field_presence.md#go-example the Golang example:
m := GetProto()
if (m.HasFoo()) {
// Clear the field:
m.Foo = nil
} else {
// Field is not present, so set it.
m.Foo = proto.Int32(1);
}
if I use:
protoc pkg/user.proto --go_out=. --go_opt=module=my_app --go-grpc_out=. --go-grpc_opt=module=my_app
with:
syntax = "proto3";
package example;
message MyPlayer {
uint64 id = 1;
optional string description = 2;
uint32 qty = 3;
optional uint64 age = 4;
}
it doesn't generate any has<T>()
method.
Why?
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.17.3
Am I wrong if I use MyPlayer
generated proto fields instead of methods?
Example:
if MyPlayer.description != nil {
description = *MyPlayer.description
}
instead of
description = MyPlayer.GetDescription()
which is not what I want (I want to detect nil values).
答案1
得分: 3
这份文档是错误的,如此处所述:https://github.com/golang/protobuf/issues/1336:
https://github.com/protocolbuffers/protobuf/blob/master/docs/field_presence.md#go-example 上的文档是错误的。在 proto3 中使用 "optional" 会生成与 proto2 中相同的字段。
那份文档是错误的。生成的代码中没有
Has
方法。通过将字段与nil
进行比较来测试是否存在。
正确重写这些示例:
// 字段 foo 没有存在性。 // 如果字段 foo 不为 0,则将其设置为 0。 // 如果字段 foo 为 0,则将其设置为 1。 m := GetProto() if m.Foo != 0 { // “清除”字段: m.Foo = 0 } else { // 默认值:字段可能不存在。 m.Foo = 1 }
// 字段 foo 有存在性。 // 如果 foo 已设置,则清除它。 // 如果 foo 未设置,则将其设置为 1。 m := GetProto() if m.Foo != nil { // 清除字段: m.Foo = nil } else { // 字段不存在,因此设置它。 m.Foo = proto.Int32(1) }
修复该文档的 PR:
protocolbuffers/protobuf#8788
英文:
That docs is wrong, as reported here: https://github.com/golang/protobuf/issues/1336:
> The documentation on https://github.com/protocolbuffers/protobuf/blob/master/docs/field_presence.md#go-example is incorrect. Using "optional" in proto3 makes the field be generated just as it would in proto2.
> That doc is wrong. There are no Has
methods in the generated code. Test for presence by comparing fields to nil
.
>
> Rewriting those examples correctly:
>
>
> // Field foo does not have presence.
> // If field foo is not 0, set it to 0.
> // If field foo is 0, set it to 1.
> m := GetProto()
> if m.Foo != 0 {
> // "Clear" the field:
> m.Foo = 0
> } else {
> // Default value: field may not have been present.
> m.Foo = 1
> }
>
>
>
> // Field foo has presence.
> // If foo is set, clear it.
> // If foo is not set, set it to 1.
> m := GetProto()
> if m.Foo != nil {
> // Clear the field:
> m.Foo = nil
> } else {
> // Field is not present, so set it.
> m.Foo = proto.Int32(1)
> }
>
> PR to fix that doc:
> protocolbuffers/protobuf#8788
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论