Protobuf3:如何描述重复字符串的映射? [英] Protobuf3: How to describe map of repeated string?
问题描述
关于地图类型的官方文档 说:
<块引用>map
...其中 key_type 可以是任何整数或字符串类型(因此,任何标量类型,浮点类型和字节除外).值类型可以是任何类型.
我想定义一个 map
字段,但它在我的 libprotoc 3.0.0
上似乎是非法的,它抱怨 Expected ">"
.所以想知道有没有什么办法可以把重复的字符串放到map中.
可能的解决方法是:
message ListOfString {重复字符串值 = 1;}//然后定义:mapmapToRepeatedString = 1;
但是 ListOfString
在这里看起来是多余的.
我有同样的需求,但遇到了同样的错误.我不相信这是可能的.以下是语言规范中的相关 BNF 定义.
https://developers.google.com/protocol-buffers/文档/参考/proto3-spec
messageType = [ "."] { 标识."} 消息名称mapField = "地图" "<"键类型,"类型>"mapName "=" fieldNumber [ "["fieldOptions "]" ] ";"类型 = "双" |浮动" |"int32" |"int64" |"uint32" |uint64"|"sint32" |"sint64" |"fixed32" |"fixed64" |"sfixed32" |sfixed64"|"布尔" |字符串" |字节" |消息类型 |枚举类型消息名称 = 身份ident = 字母 { 字母 |十进制数字|_"}field = [ "repeated" ] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
repeated"关键字只出现在字段定义中.地图定义需要一个类型",不包括重复的关键字.
这意味着有几个选项.
- 您可以按照您的指示在重复值周围创建一个包装器.
- 人们定义地图的方式较旧,虽然繁琐但等效.这是语言指南中的向后兼容示例.https://developers.google.com/protocol-buffers/docs/proto3#maps<预>消息 MapFieldEntry {key_type 键 = 1;重复 value_type 值 = 2;}重复 MapFieldEntry map_field = N;
您需要自己将数据转换为地图,但这在大多数语言中应该是相当简单的.在 Java 中:<预>列表
map_field =//protobuf 中的现有列表.映射 >= map_field.stream().collect(Collectors.toMap(kv -> kv.key, kv -> kv.value)); - 使用 google.protobuf.ListValuehttps://developers.google.com/protocol-buffers/docs/reference/google.protobuf#listvalue这是来自他们众所周知的类型的无类型列表集合.
The Official documentation about map type says:
map<key_type, value_type> map_field = N;
...where the key_type can be any integral or string type (so, any scalar type except for floating point types and bytes). The value_type can be any type.
I want to define a map<string, repeated string>
field, but it seems illegal on my libprotoc 3.0.0
, which complains Expected ">"
. So I wonder if there is any way to put repeated string into map.
A Possible workaround could be:
message ListOfString {
repeated string value = 1;
}
// Then define:
map<string, ListOfString> mapToRepeatedString = 1;
But ListOfString
here looks redundant.
I had the same need, and got the same error. I do not believe this is possible. Here is the relevant BNF definitions from the language specification.
https://developers.google.com/protocol-buffers/docs/reference/proto3-spec
messageType = [ "." ] { ident "." } messageName
mapField = "map" "<" keyType "," type ">" mapName "=" fieldNumber [ "["fieldOptions "]" ] ";"
type = "double" | "float" | "int32" | "int64" | "uint32" | "uint64"
| "sint32" | "sint64" | "fixed32" | "fixed64" | "sfixed32" | "sfixed64"
| "bool" | "string" | "bytes" | messageType | enumType
messageName = ident
ident = letter { letter | decimalDigit | "_" }
field = [ "repeated" ] type fieldName "=" fieldNumber [ "[" fieldOptions "]" ] ";"
"repeated" keyword only appears in the field definition. The map definition requires a "type", which does not include the repeated keyword.
That means there are a few options.
- You could create a wrapper around the repeated value as you indicated.
- There is the older way people defined define maps, which is more burdensome but is equivalent. This is the backwards compatible example from the language guide.
https://developers.google.com/protocol-buffers/docs/proto3#maps
message MapFieldEntry { key_type key = 1; repeated value_type value = 2; } repeated MapFieldEntry map_field = N;
You would need to convert the data to a map yourself, but this should be fairly trivial in most languages. In Java:
List<MapFieldEntry> map_field = // Existing list from protobuf. Map<key_type, List<value_type>> = map_field.stream() .collect(Collectors.toMap(kv -> kv.key, kv -> kv.value));
- Use google.protobuf.ListValue https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#listvalue This is an untyped list collection from their well known types.
这篇关于Protobuf3:如何描述重复字符串的映射?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!