49 votes

Dictionnaire dans les tampons de protocole

Existe-t-il un moyen de sérialiser un dictionnaire en utilisant des tampons de protocole, ou bien je devrai utiliser Thrift si j'en ai besoin ?

0 votes

1 votes

Pas vraiment en double. Cette question concernait les liaisons .net. L'OP ne précise pas l'environnement linguistique.

70voto

Flassari Points 325

Pour les futurs chercheurs de réponses, ProtoBuf supporte maintenant les cartes nativement :

message MapMessage
{
    map<string, string> MyMap = 1;
}

3 votes

Veuillez noter que les cartes ne peuvent toujours pas être répétées.

12 votes

Les cartes sont des collections, elles sont déjà répétées par définition.

0 votes

Le lien concerne la syntaxe de proto2, mais les cartes sont également disponibles en proto3. developers.google.com/protocol-buffers/docs/proto3#maps

57voto

JesperE Points 34356

Spécification de Protobuf maintenant supporte nativement les dictionnaires (maps) .

Réponse originale

Les gens écrivent généralement le dictionnaire sous la forme d'une liste de paires clé-valeur, puis reconstruisent le dictionnaire à l'autre bout.

message Pair {
   string key = 1;
   string value = 2;
}

message Dictionary {
   repeated Pair pairs = 1;
}

2 votes

Existe-t-il un moyen de faire la même chose avec un type dynamique ? J'ai un type Dictionary<string,object> que je dois sérialiser. =/ J'essayais de voir si les tampons de protocole pouvaient le faire sans un effort énorme.

3 votes

Eh bien, non. Protobuf n'est pas un protocole général de sérialisation d'objets. Vous devez définir des messages protobuf pour toutes les données que vous voulez sérialiser. (Honnêtement, si vous avez une carte <chaîne, objet>, vous devriez probablement commencer par refactorer votre code).

0 votes

@Mike Vous devriez créer un champ pour chaque type de produit. pourrait être, ce qui est un bug qui ne demande qu'à se produire.

1voto

Zheng Xu Points 56

Vous pouvez vérifier le ProtoText paquet.

Supposons que vous voulez sérialiser un dict person_dict à une valeur prédéfinie PersonBuf objet protobuf défini dans personbuf_pb2 module.

Dans ce cas, pour utiliser ProtoText,

import ProtoText
from personbuf_pb2 import PersonBuf

obj = PersonBuf()
obj.update(person_dict)

0voto

Emixam23 Points 913

Je commente d'abord la réponse de @Flassari car elle est vraiment pratique.

Cependant, dans mon cas, j'avais besoin map<Type, repeated AnyModel> où :

enum Type {
    Undefined = 0;
    Square = 1;
    Circle = 2;
}

message AnyModel {
    string Name = 1;
}

Ici, je veux juste retourner un dictionnaire qui, pour chaque type, contient une liste de AnyModel

Cependant, je n'ai pas trouvé de meilleure solution que celle proposée par @JesperE et j'ai donc fait ce qui suit : ( car vous ne pouvez pas utiliser un enum comme clé dans une map. )

message MyRPCBodyCall {
    map<string, AnyModels> Models = 1;
}

enum Type {
    Undefined = 0;
    Square = 1;
    Circle = 2;
}

message AnyModel {
    string Name = 1;
}

message AnyModelArray {
    repeated AnyModel AnyModels = 1;
}

Ici, je convertis de/en string mon enum en utilisant les langages de code de mon choix, tant du côté serveur que client.

Les deux approches sont donc des réponses valables, selon vos besoins.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X