在 protobuf 消息中将值类型 float 的现有字段更改为可选的 float
Change an existing field of value type float to an optional float in a protobuf message
我有以下类型的消息
message Foo {
string bar = 1;
float baz = 2;
}
转换成下面的形式在Go中使用有问题吗?
message Foo {
string bar = 1;
optional float baz = 2;
}
在这种情况下,弃用和在原型中创建新字段的首选方式也是如此吗?
optional
将使字段成为指针类型。所以在Go生成的代码中,optional float
会变成*float32
,当然是不是float32
.
要弃用字段,请使用 [deprecated = true]
字段选项:
message Foo {
string bar = 1;
float baz = 2 [deprecated = true];
}
如果在您的 protobuf 架构的后续版本中您实际上从消息中完全删除了该字段,您可能需要添加 reserved 2
,其中 2
是您删除的字段的编号。
message Foo {
string bar = 1;
reserved 2;
}
这有助于防止其他人或未来的您在位置 2 中添加新字段。如果您有过时的客户仍然希望在位置 2 中有 float
,这很重要。
PS:optional
Proto3 中的字段从版本 3.15 开始得到支持
取决于特定消息在您的代码库中的集成程度 - 意思是
- 您是否将编组的二进制表示存储在数据库之类的地方
- 您的代码库的不同部分使用您正在修改的消息的不同版本 - 例如您的 android/ios 应用的旧版本等
要点是,如果您使用消息结构来解组编码数据(不是使用完全相同的消息结构生成的),就会发生坏事。
文档建议添加一个新元素以完全避免此类情况。如果您不想这样做,请考虑以上几点。
我建议您使用 FloatValue type defined in the google.protobuf 包。例如:
syntax = "proto3";
import "google/protobuf/wrappers.proto";
message Foo {
string bar = 1;
google.protobuf.FloatValue baz = 2;
}
将生成一个 pb 文件,内容为:
type Foo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Bar string `protobuf:"bytes,1,opt,name=bar,proto3" json:"bar,omitempty"`
Baz *wrapperspb.FloatValue `protobuf:"bytes,2,opt,name=baz,proto3" json:"baz,omitempty"`
}
您可以按如下方式使用:
f := Foo{
Bar: "Bar",
Baz: &wrapperspb.FloatValue{Value: float32(3)},
}
var floatValue float32
if f.Baz != nil {
floatValue = f.Baz.GetValue()
}
我有以下类型的消息
message Foo {
string bar = 1;
float baz = 2;
}
转换成下面的形式在Go中使用有问题吗?
message Foo {
string bar = 1;
optional float baz = 2;
}
在这种情况下,弃用和在原型中创建新字段的首选方式也是如此吗?
optional
将使字段成为指针类型。所以在Go生成的代码中,optional float
会变成*float32
,当然是不是float32
.
要弃用字段,请使用 [deprecated = true]
字段选项:
message Foo {
string bar = 1;
float baz = 2 [deprecated = true];
}
如果在您的 protobuf 架构的后续版本中您实际上从消息中完全删除了该字段,您可能需要添加 reserved 2
,其中 2
是您删除的字段的编号。
message Foo {
string bar = 1;
reserved 2;
}
这有助于防止其他人或未来的您在位置 2 中添加新字段。如果您有过时的客户仍然希望在位置 2 中有 float
,这很重要。
PS:optional
Proto3 中的字段从版本 3.15 开始得到支持
取决于特定消息在您的代码库中的集成程度 - 意思是
- 您是否将编组的二进制表示存储在数据库之类的地方
- 您的代码库的不同部分使用您正在修改的消息的不同版本 - 例如您的 android/ios 应用的旧版本等
要点是,如果您使用消息结构来解组编码数据(不是使用完全相同的消息结构生成的),就会发生坏事。
文档建议添加一个新元素以完全避免此类情况。如果您不想这样做,请考虑以上几点。
我建议您使用 FloatValue type defined in the google.protobuf 包。例如:
syntax = "proto3";
import "google/protobuf/wrappers.proto";
message Foo {
string bar = 1;
google.protobuf.FloatValue baz = 2;
}
将生成一个 pb 文件,内容为:
type Foo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Bar string `protobuf:"bytes,1,opt,name=bar,proto3" json:"bar,omitempty"`
Baz *wrapperspb.FloatValue `protobuf:"bytes,2,opt,name=baz,proto3" json:"baz,omitempty"`
}
您可以按如下方式使用:
f := Foo{
Bar: "Bar",
Baz: &wrapperspb.FloatValue{Value: float32(3)},
}
var floatValue float32
if f.Baz != nil {
floatValue = f.Baz.GetValue()
}