Flatbuffers: как разрешить несколько типов для одного поля

Я пишу схему протокола связи для списка параметров, которые могут иметь несколько значений: 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];
}
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
918
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В настоящее время вы не можете помещать скаляры непосредственно в объединение, поэтому вам придется обернуть их в таблицу или структуру, где структура, вероятно, будет наиболее эффективной, например.

struct UInt64 { u:uint64 }
union ParameterValue { UInt64, Float64, Bool, string }

Это связано с тем, что объединение должно быть одинакового размера, поэтому оно допускает только типы, для которых вы можете иметь смещение.

Однако, как правило, FlatBuffers является строго типизированной системой, и схема, которую вы создаете здесь, отменяет это, эмулируя динамически типизированные данные, поскольку ваши данные, по сути, представляют собой список пар (строка, любой тип). Вам может быть лучше с системой, разработанной для этого конкретного варианта использования, такой как FlexBuffers (https://google.github.io/flatbuffers/flexbuffers.html, в настоящее время только C++), которая явно имеет тип карты, который представляет собой все строки -> любые пары типов.

Конечно, еще лучше не хранить данные в таком общем виде, а вместо этого создать новую схему для каждого типа запроса и ответа, которые у вас есть, и преобразовать имена параметров в поля, а не в сериализованные данные. Это, безусловно, самый эффективный и безопасный тип.

Спасибо за информацию, Ардаппель, в итоге я подумал об альтернативном решении (вектор объединения), которое тоже нехорошо, поскольку нам нужны другие языки, кроме С++. Наконец-то я сделал, как вы упомянули, с отдельной таблицей для каждого типа. Спасибо

Sebastien De Varennes 30.01.2019 18:41

Судя по всему, объединения могут быть только таблиц в определенных языках, поэтому я не могу сделать объединение структур. Я все еще могу превратить эти структуры в таблицы и объединить их.

Sebastien De Varennes 30.01.2019 19:24

Другие вопросы по теме