Skip to content

omitempty

默认行为

在使用 protoc 3 时,默认会为所有标量字段(包括字符串)添加 omitempty 标签。这是 protobuf 3 的一个默认行为。要解决这个问题,有几种方式:

gogoproto

例子1

Input
proto
message Config {
  int64 id = 1;
  string name = 2 [(gogoproto.jsontag) = "name"];
  string desc = 3 [(gogoproto.jsontag) = "desc"];
  Role role = 5 [(gogoproto.nullable) = false];
}
Output
go
type Config struct {
    Id   int64  `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
    Name string `protobuf:"bytes,2,opt,name=name" json:"name"`
    Desc string `protobuf:"bytes,3,opt,name=desc" json:"desc"`
    Role Role   `protobuf:"bytes,5,opt,name=role" json:"role"`
}

例子2

Input
proto
message Config {
  int64 id = 1;
  string name = 2 [(gogoproto.jsontag) = "name,omitempty"];
  string desc = 3 [(gogoproto.jsontag) = "desc,omitempty"];
  Role role = 5 [
    (gogoproto.nullable) = true,
    (gogoproto.jsontag) = "role,omitempty"
  ];
}
Output
go
type Config struct {
    Id   int64  `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
    Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
    Desc string `protobuf:"bytes,3,opt,name=desc" json:"desc,omitempty"`
    Role *Role  `protobuf:"bytes,5,opt,name=role" json:"role,omitempty"`
}
  • omitempty 只对指针类型或可为零值的字段生效。
  • 如果你设置了 (gogoproto.nullable) = falseRole 是值类型(Role 而不是 *Role),即使 omitempty 写上了,也不会生效,因为值类型永远不会是 nil
  • 所以想让 omitempty 生效,必须同时确保字段是指针类型(即 nullable = true 或省略)。

例子3

Input
proto
message Config {
  Role role = 5;
}
Output
go
type Config struct {
    Role *Role `protobuf:"bytes,5,opt,name=role" json:"role,omitempty"`
}

Global

jsx
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
option (gogoproto.goproto_getters_all) = false;
option (gogoproto.enum_stringer_all) = true;