1

在 PHP 客户端和 Python 服务器上拥有这个 proto3 模式:

service GetAnimalData{
    rpc GetData (AnimalRequest) returns (AnimalData) {}
}

message AnimalRequest {
    OneOfAnimal TypeAnimal = 1;
}

message AnimalData {
    repeated int32 data = 1;
}

message OneOfAnimal {
    oneof animal_oneof {
        CAT cat = 1;
        DOG dog = 2;
    }
}

message CAT{
    int32 p = 1;
    int32 d = 2;
    int32 q = 3;
}

message DOG{
    int32 p = 1;
    int32 d = 2;
    int32 q = 3;
    int32 p2 = 4;
    int32 d2 = 5;
    int32 q2 = 6;
}

为了设置来自 PHP 客户端的请求,我需要执行以下操作:

  1. 创建一个新的CAT
  2. 设置OneOfAnimalCAT
  3. 设置AnimalRequest.TypeAnimalOneOfAnimal

是否有 proto3 的架构,我可以直接将 aCATDOGobject 设置为我的AnimalRequest.TypeAnimal

4

1 回答 1

2

笼统; 不,不是。

在某些非常具体的情况下,答案是“是”——例如,protobuf-net(.NET 中的“代码优先”protobuf 实现)恰好以这种方式实现继承因此您可以使用:

[ProtoContract]
public class AnimalRequest {
    [ProtoMember(1)] public Animal Animal {get;set;}
}

[ProtoContract]
[ProtoInclude(1, typeof(Cat))]
[ProtoInclude(2, typeof(Dog))]
class Animal {} // acts identically to your OneOfAnimal message type

[ProtoContract]
class Cat {
    [ProtoMember(1)] public int P {get;set;}
    [ProtoMember(2)] public int D {get;set;}
    [ProtoMember(3)] public int Q {get;set;}
}

[ProtoContract]
class Dog {
    [ProtoMember(1)] public int P {get;set;}
    [ProtoMember(2)] public int D {get;set;}
    [ProtoMember(3)] public int Q {get;set;}
    [ProtoMember(4)] public int P2 {get;set;}
    [ProtoMember(5)] public int D2 {get;set;}
    [ProtoMember(6)] public int Q2 {get;set;}
}

然后你使用:

var result = svc.GetData(
    new AnimalRequest { Animal = new Dog { P = 42, ... Q2 = 19 } }
);

它会以完全相同的方式工作——发送相同的字节;本质上,protobuf-net 将继承视为oneof(在类型层次结构中的每个级别)。

但是:因为.proto旨在以非常通用的“最小公分母”方式工作,.proto它本身没有继承的概念,所以:你不能从.proto谷歌库或谷歌库中做到这一点。

于 2020-06-17T08:14:02.980 回答