将Protobuf消息中现有的值类型为float的字段更改为可选的float类型。

huangapple go评论86阅读模式
英文:

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;
}

在这种情况下,是否首选废弃并在proto中创建一个新字段?

英文:

I have a message of the following type

message Foo {
    string bar = 1;
    float baz = 2;
}

Is there any problem in converting it to the following for use in Go ?


message Foo {
    string bar = 1;
    optional float baz = 2;
}

Is the preferred way to deprecate and create a new field in the proto in this case as well ?

答案1

得分: 0

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:Proto3中的optional字段从3.15版本开始支持。

英文:

The optional will make the field a pointer type. So in Go generated code, optional float will become *float32, which of course is not float32.

To deprecate a field, use [deprecated = true] field option:

message Foo {
    string bar = 1;
    float baz = 2 [deprecated = true];
}

If in subsequent releases of your protobuf schema you actually remove the field altogether from the message, you might want to add reserved 2, where 2 is the number of the field you removed.

message Foo {
    string bar = 1;
    reserved 2;
}

This helps preventing other people or future you from adding a new field in position 2. This is relevant in case you have outdated clients which still expect a float in position 2.

PS: optional fieds in Proto3 are supported from version 3.15

答案2

得分: 0

这取决于该特定消息在你的代码库中的集成程度,也就是说:

  1. 你是否将编组的二进制表示存储在某个地方,比如数据库?
  2. 你的代码库的不同部分是否在使用你正在修改的消息的不同版本,比如旧版本的 Android/iOS 应用等?

关键在于,如果你使用消息结构来解组编码数据,而该数据的生成不是使用完全相同的消息结构,那么会发生糟糕的事情。

文档建议添加一个新元素来完全避免这种情况。如果这不是你想要做的事情,那么请考虑上述要点。

英文:

depends on how deeply integrated that particular message is in your code base - meaning

  1. are you storing the marshaled binary representation somewhere like your database
  2. are different parts of your code base using different versions of the message you are modifying - e.g. older versions of your android/ios apps and such

point being if you use a message structure to unmarshal encoded data, that was not generated with the very same message structure, into - bad things will happen.

The docs recommend adding a new element to circumvent such scenarios entirely. If that is not something you want to do, take the above points into consideration.

答案3

得分: 0

我建议您使用在google.protobuf包中定义的FloatValue类型。例如:

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()
}
英文:

I suggest you to use the FloatValue type defined in the google.protobuf package. As example:


syntax = "proto3";

import "google/protobuf/wrappers.proto";

message Foo {
  string bar = 1;
  google.protobuf.FloatValue baz = 2;
}

Will generate a pb files with the content:


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"`
}


You can use as follow:

  f := Foo{
	  Bar:           "Bar",
	  Baz:           &wrapperspb.FloatValue{Value: float32(3)},
  }

  var floatValue float32 
  if f.Baz != nil {
	  floatValue = f.Baz.GetValue()
  }


huangapple
  • 本文由 发表于 2021年10月2日 13:28:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/69414245.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定