Flatbuffers:如何为单个字段允许多种类型
Flatbuffers: How to allow multiple types for a single field
我正在为可以具有多个值的参数列表编写通信协议模式:uint64、float64、string 或 bool。
如何将 table 字段设置为多个原始标量和非标量原始类型的联合?
我已经尝试过使用这些类型的联合,但在构建时出现以下错误:
$ schemas/foobar.fbs:28: 0: error: type referenced but not defined
(check namespace): uint64, originally at: schemas/request.fbs:5
这是当前状态下的模式:
namespace Foobar;
enum RequestCode : uint16 { Noop, Get, Set, BulkGet, BulkSet }
union ParameterValue { uint64, float64, bool, string }
table Parameter {
name:string;
value:ParameterValue;
unit:string;
}
table Request {
code:RequestCode = Noop;
payload:[Parameter];
}
table Result {
request:Request;
success:bool = true;
payload:[Parameter];
}
我正在寻找的最终结果是包含参数列表的请求和结果 table,其中参数包含名称和值,以及可选的单位。
提前致谢!
Post-答案解答:
这是我最后想到的,感谢 Aardappel。
namespace foobar;
enum RequestCode : uint16 { Noop, Get, Set, BulkGet, BulkSet }
union ValueType { UnsignedInteger, SignedInteger, RealNumber, Boolean, Text }
table UnsignedInteger {
value:uint64 = 0;
}
table SignedInteger {
value:int64 = 0;
}
table RealNumber {
value:float64 = 0.0;
}
table Boolean {
value:bool = false;
}
table Text {
value:string (required);
}
table Parameter {
name:string (required);
valueType:ValueType;
unit:string;
}
table Request {
code:RequestCode = Noop;
payload:[Parameter];
}
table Result {
request:Request (required);
success:bool = true;
payload:[Parameter];
}
您目前不能将标量直接放在联合中,因此您必须将它们包装在 table 或结构中,其中结构可能是最有效的,例如
struct UInt64 { u:uint64 }
union ParameterValue { UInt64, Float64, Bool, string }
这是因为联合必须具有统一的相同大小,所以它只允许可以有偏移量的类型。
一般来说,FlatBuffers 是一个强类型系统,您在此处创建的模式正在通过模拟动态类型数据来取消它,因为您的数据本质上是一个(字符串,任何类型)对列表。使用专为该特定用例设计的系统可能会更好,例如 FlexBuffers(https://google.github.io/flatbuffers/flexbuffers.html,目前只有 C++),它明确具有一个映射类型,即所有字符串 -> 任何类型对。
当然,更好的方法是不要将数据存储得如此通用,而是为您拥有的每种类型的请求和响应创建一个新的模式,并将参数名称制作成字段,而不是序列化数据。这是迄今为止最有效的,并且类型安全。
我正在为可以具有多个值的参数列表编写通信协议模式:uint64、float64、string 或 bool。
如何将 table 字段设置为多个原始标量和非标量原始类型的联合?
我已经尝试过使用这些类型的联合,但在构建时出现以下错误:
$ schemas/foobar.fbs:28: 0: error: type referenced but not defined
(check namespace): uint64, originally at: schemas/request.fbs:5
这是当前状态下的模式:
namespace Foobar;
enum RequestCode : uint16 { Noop, Get, Set, BulkGet, BulkSet }
union ParameterValue { uint64, float64, bool, string }
table Parameter {
name:string;
value:ParameterValue;
unit:string;
}
table Request {
code:RequestCode = Noop;
payload:[Parameter];
}
table Result {
request:Request;
success:bool = true;
payload:[Parameter];
}
我正在寻找的最终结果是包含参数列表的请求和结果 table,其中参数包含名称和值,以及可选的单位。
提前致谢!
Post-答案解答: 这是我最后想到的,感谢 Aardappel。
namespace foobar;
enum RequestCode : uint16 { Noop, Get, Set, BulkGet, BulkSet }
union ValueType { UnsignedInteger, SignedInteger, RealNumber, Boolean, Text }
table UnsignedInteger {
value:uint64 = 0;
}
table SignedInteger {
value:int64 = 0;
}
table RealNumber {
value:float64 = 0.0;
}
table Boolean {
value:bool = false;
}
table Text {
value:string (required);
}
table Parameter {
name:string (required);
valueType:ValueType;
unit:string;
}
table Request {
code:RequestCode = Noop;
payload:[Parameter];
}
table Result {
request:Request (required);
success:bool = true;
payload:[Parameter];
}
您目前不能将标量直接放在联合中,因此您必须将它们包装在 table 或结构中,其中结构可能是最有效的,例如
struct UInt64 { u:uint64 }
union ParameterValue { UInt64, Float64, Bool, string }
这是因为联合必须具有统一的相同大小,所以它只允许可以有偏移量的类型。
一般来说,FlatBuffers 是一个强类型系统,您在此处创建的模式正在通过模拟动态类型数据来取消它,因为您的数据本质上是一个(字符串,任何类型)对列表。使用专为该特定用例设计的系统可能会更好,例如 FlexBuffers(https://google.github.io/flatbuffers/flexbuffers.html,目前只有 C++),它明确具有一个映射类型,即所有字符串 -> 任何类型对。
当然,更好的方法是不要将数据存储得如此通用,而是为您拥有的每种类型的请求和响应创建一个新的模式,并将参数名称制作成字段,而不是序列化数据。这是迄今为止最有效的,并且类型安全。