openlang

Обращение к содержимому объединения вызывает панику

Здравствуйте, это уже немного сводит меня с ума. Я использую довольно приятную оконную библиотеку (https://github.com/ypsvlq/wio), следуя этим указаниям (https://github.com/ypsvlq/wio/tree/master?tab=readme-ov-file#wayland), чтобы получить доступ к API wayland.

Однако любое обращение к объединению .backend с любым значением сразу вызывает панику invalid enum value, а причину я понять не могу. Я ожидал, что неправильный доступ к объединению будет отвергнут при компиляции, и проверка типа показывает ожидаемые field_names, но во время выполнения панику вызывает как правильный член (.wayland в моём случае), так и неправильный (.x11). Не вижу и ничего, из-за чего значение могло бы оказаться undefined в момент обращения.

Что вообще происходит??

Переведено с английскогоПоказать оригинал

Разговор продолжается 5

Следуя доводам
  1. Ссылка на ответ

    Проверка безопасности выдаёт invalid enum value при переключении по enum, содержащему недопустимое значение.

    Доступ к полю объединения тоже проверяется, судя по сообщению об ошибке, через switch.

    Как предположил why17, объединение, вероятно, содержит undefined, поэтому его тег тоже undefined.

    Переведено с английскогоПоказать оригинал
  2. Ссылка на ответ

    Просмотрев этот участок кода, я не вижу здесь объединений, выбранный backend зависит от os и целевой платформы сборки и определяется во время компиляции.

    После вызова wio.init backend должен быть инициализирован (либо инициализация должна вернуть ошибку), а до выполнения wio.init, вызывающего backend.init(options), значения backend ещё не инициализированы и все их значения по умолчанию в этот момент undefined:

    https://github.com/ypsvlq/wio/blob/dd0f273fdbbd1ced2a8e716ea3a5526a6c4d83cf/src/unix.zig#L20-L98

    Не понимаю такой сильной зависимости библиотеки от синглтонов и переменных уровня контейнера, инициализированных в undefined, мне это настолько не нравится, что я, скорее всего, выбрал бы другую библиотеку.

    Вместо делегирования backend библиотека wio могла бы хранить статически выбранный backend в поле обычной структуры, избегая синглтона, чей backend существует в непригодном состоянии ещё до инициализации.

    Похоже на чрезмерное стремление скрыть детали из API за повсеместными глобальными переменными.

    Переведено с английскогоПоказать оригинал
  3. Ссылка на ответ

    Речь именно о unix.Window, объединении реализаций wayland и x11.

    Я совершенно упустил, что ошибка возникает в callback события изменения размера, который, видимо, вызывается прямо во время Window.init, а я читаю именно ту переменную, которая должна содержать сейчас инициализируемое окно, так что это и объясняет наблюдаемую проблему. Это… ещё одно решение в дизайне, которое мне не очень нравится, но достойных альтернативных библиотек я пока не нашёл.

    Любопытно, что сбой происходит именно при обращении к объединению, если сама переменная окна содержит undefined, разве чтение её члена .backend не должно завершиться ошибкой ещё раньше?

    Переведено с английскогоПоказать оригинал

Другие стороны того же вопроса

  1. Отложить изменяемое заимствование блока очистки до его исполнения

    Как написать в Rust устойчивую к панике конструкцию, похожую на Java try { ... } finally { ... }, чтобы блоки try и finally м…

    Ответы 2Последняя активность rust
  2. Ввод массивов символов через указатели

    Когда пытаюсь вводить с клавиатуры данные в массивы char, программа каждый раз падает. Как можно удобно считывать с клавиатур…

    Ответы 2Последняя активность c
  3. Может ли функция ввода обойтись без глобальных переменных?

    Хочу написать функцию, которая обрабатывает пользовательский ввод, фильтрует его и возвращает полученную строку вызвавшей её…

    Ответы 2Последняя активность c