Я пишу схему протокола связи для списка параметров, которые могут иметь несколько значений: uint64, float64, string или bool.
Как я могу установить поле таблицы для объединения нескольких примитивных скалярных и нескалярных примитивных типов?
Я уже пробовал использовать объединение этих типов, но при сборке получаю следующую ошибку:
$ 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];
}
Конечным результатом, который я ищу, являются таблицы Request и Result, содержащие список параметров, где параметр содержит имя и значение, а также, возможно, единицы измерения.
Спасибо заранее!
Решение после ответа: Вот что у меня получилось в итоге, спасибо 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];
}





В настоящее время вы не можете помещать скаляры непосредственно в объединение, поэтому вам придется обернуть их в таблицу или структуру, где структура, вероятно, будет наиболее эффективной, например.
struct UInt64 { u:uint64 }
union ParameterValue { UInt64, Float64, Bool, string }
Это связано с тем, что объединение должно быть одинакового размера, поэтому оно допускает только типы, для которых вы можете иметь смещение.
Однако, как правило, FlatBuffers является строго типизированной системой, и схема, которую вы создаете здесь, отменяет это, эмулируя динамически типизированные данные, поскольку ваши данные, по сути, представляют собой список пар (строка, любой тип). Вам может быть лучше с системой, разработанной для этого конкретного варианта использования, такой как FlexBuffers (https://google.github.io/flatbuffers/flexbuffers.html, в настоящее время только C++), которая явно имеет тип карты, который представляет собой все строки -> любые пары типов.
Конечно, еще лучше не хранить данные в таком общем виде, а вместо этого создать новую схему для каждого типа запроса и ответа, которые у вас есть, и преобразовать имена параметров в поля, а не в сериализованные данные. Это, безусловно, самый эффективный и безопасный тип.
Судя по всему, объединения могут быть только таблиц в определенных языках, поэтому я не могу сделать объединение структур. Я все еще могу превратить эти структуры в таблицы и объединить их.
Спасибо за информацию, Ардаппель, в итоге я подумал об альтернативном решении (вектор объединения), которое тоже нехорошо, поскольку нам нужны другие языки, кроме С++. Наконец-то я сделал, как вы упомянули, с отдельной таблицей для каждого типа. Спасибо