我正在尝试长期序列化一堆与java中强类层次结构相关的对象,并且由于它们的简单性,性能和易于升级,我想使用协议缓冲区来实现它.但是,它们并没有为多态性提供太多支持.现在,我正在处理它的方式是通过"一条消息来统治它们"的解决方案,它有一个必需的字符串uri字段,允许我通过反射实例化正确的类型,然后是一堆可选字段,用于所有我可以序列化的其他可能的类,只使用其中一个(基于uri字段的值).有没有更好的方法来处理多态,或者这是否会像我将得到的那样好?
Ric*_*kyA 36
在proto3中,extend关键字已被替换.来自文档:If you are already familiar with proto2 syntax, the Any type replaces extensions.
syntax = "proto3";
import "google/protobuf/any.proto";
message Foo {
  google.protobuf.Any bar = 1;
}
但要注意:Any本质上是一个字节blob.大多数时候最好使用Oneof:
syntax = "proto3";
message A {
    string a = 1;
}
message B {
    string b = 1;
}
message Foo {
  oneof bar {
    A a = 1;
    B b = 2;
  }
}
Jon*_*ise 33
有一些实现多态的技术.我试着在这里覆盖它们:Protocol Buffer Polymorphism
我首选的方法使用嵌套扩展:
message Animal
{
    extensions 100 to max;
    enum Type
    {
        Cat = 1;
        Dog = 2;
    }
    required Type type = 1;
}
message Cat
{
    extend Animal
    {
        required Cat animal = 100; // Unique Animal extension number
    }
    // These fields can use the full number range.
    optional bool declawed = 1;
}
message Dog
{
    extend Animal
    {
        required Dog animal = 101; // Unique Animal extension number
    }
    // These fields can use the full number range.
    optional uint32 bones_buried = 1;
}
小智 5
Jon的解决方案是正确的,但却非常奇怪(对我而言).但是协议缓冲区很简单,所以你可以这样做:
enum Type {
    FOO = 0;
    BAR = 1;
  }
message Foo {
  required Type type = 1;
}
message Bar {
  required Type type = 1;
  required string text = 2;
}
基本上消息栏扩展消息Foo(当然从实际方面).Java中的实现也很简单:
Bar bar = Bar.newBuilder().setType(Type.BAR).setText("example").build();
byte[] data = bar.toByteArray();
----
Foo foo = Foo.parseFrom(data);
if(foo.getType() == Type.BAR){
   Bar bar = Bar.parseFrom(data);
   System.out.println(bar.getText());
}
我知道,这不是一个优雅的解决方案,但它简单而合乎逻辑.
| 归档时间: | 
 | 
| 查看次数: | 37141 次 | 
| 最近记录: |