2016-08-11 2 views
2

Official documentation about map type говорит:Protobuf3: Как описать карту повторяющейся строки?

map<key_type, value_type> map_field = N;

... где key_type может быть любым целым или строкового типа (так, любой типа скалярных для плавающих типов и байты, за исключением). Значение value_type может быть любого типа.

Я хочу, чтобы определить map<string, repeated string> поле, но, кажется незаконным на моем libprotoc 3.0.0, который жалуется Expected ">". Поэтому я задаюсь вопросом, есть ли способ нанести повторяющуюся строку на карту.

Возможный обходной путь может быть:

message ListOfString { 
    repeated string value = 1; 
} 

// Then define: 
map<string, ListOfString> mapToRepeatedString = 1; 

Но ListOfString здесь выглядит излишним.

+0

Просто проверять основы :) Установили ли вы синтаксис = "proto3"; '? – Mark

ответ

3

У меня была такая же потребность, и у меня такая же ошибка. Я не считаю, что это возможно. Вот соответствующие определения BNF из спецификации языка.

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 "]" ] ";" 

"повторяется" ключевое слово появляется только в определении поля. Для определения карты требуется «тип», который не включает повторяющееся ключевое слово.

Это означает, что есть несколько вариантов.

  • Вы можете создать обертку вокруг повторяющегося значения, как вы указали.
  • Существует более старый способ определения людьми определений карт, что является более обременительным, но эквивалентным. Это обратный совместимый пример из руководства по языку. 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; 
    
    Вы должны преобразовать данные в карту самостоятельно, но это должно быть довольно тривиально в большинстве языков. В 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)); 
    
    
  • Использование google.protobuf.ListValue https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#listvalue Это нетипизированная коллекция список от их хорошо известных типов.
Смежные вопросы