openlang

访问联合的载荷时发生 panic

你好,这有点把我逼疯了。我在用这个挺不错的窗口库(https://github.com/ypsvlq/wio ),按照这些说明(https://github.com/ypsvlq/wio/tree/master?tab=readme-ov-file#wayland )来访问 wayland API。

但无论用什么值访问 .backend 联合,都会立刻发生 invalid enum value panic,我找不出原因。我以为错误访问联合会在编译时被拒绝,查看类型也能看到预期的 field_names,但在运行时用正确的成员(这里是 .wayland)或错误的成员(.x11)都会 panic。我也没看出有什么会让这个值在访问时处于 undefined 状态。

这是怎么回事??

从英语翻译查看原文

后续讨论 5

顺着彼此的依据读下去
  1. 固定链接

    对包含无效值的 enum 做 switch 时,安全检查会产生 invalid enum value。

    访问联合字段也有安全检查,从错误信息来看,似乎也是通过 switch 来检查的。

    像 why17 说的那样,联合里可能是 undefined,所以它的标签也是 undefined。

    从英语翻译查看原文
  2. 固定链接

    看了这部分代码,我没发现这里涉及联合,使用哪个后端是在编译期根据 os 和构建目标决定的。

    调用 wio.init 后,后端应该已经初始化了,或者初始化返回错误,而在 wio.init 执行并调用 backend.init(options) 之前,后端的值都还没初始化,当时的默认值全部是 undefined。

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

    我不太理解这个库为什么这么依赖单例和初始化为 undefined 的容器级变量,我很不喜欢这种做法,可能会因此选别的库。

    wio 可以把静态选定的后端放在普通 struct 的字段中,而不是向后端委托,这样就能避免一个在初始化前已经存在却无法使用的后端单例。

    它似乎过于执着于用大量全局变量把细节从 API 中藏起来。

    从英语翻译查看原文
  3. 固定链接

    我具体说的是 unix.Window,它是包含 wayland 和 x11 实现的联合。

    我完全没注意到错误出在调整大小事件的回调里,这个回调似乎会在 Window.init 期间立即调用,而我读取的正是应该存放当前正在初始化的窗口的那个变量,这就能解释我看到的问题了。这……也是个我不太喜欢的设计选择,不过我还没找到什么像样的替代库。

    奇怪的是,出错的偏偏是联合访问,如果窗口变量本身就是 undefined,那读取它的 .backend 成员时不就应该先失败了吗?

    从英语翻译查看原文

同一个问题的其他角度

  1. 让清理块真正执行时才开始可变借用

    怎样在 Rust 中写一个 panic 安全的机制,类似 Java 的 try { ... } finally { ... },同时允许 try 和 finally 块分别可变借用同一个值? 我需要的是,无论正常离开还是因 panic 栈展开而离开…

    回复 2最近活动 rust
  2. 通过指针输入字符数组

    每次尝试从键盘往一些 char 数组里输入内容,程序最后都会崩溃。 有什么简单方便的方法,可以从键盘读取 char 数组并保存下来?

    回复 2最近活动 c
  3. 输入函数能不依赖全局变量吗?

    我想写一个函数,处理并过滤用户输入,然后把得到的字符串返回给调用它的函数。 能不能不声明下面例子中的这种全局变量,也实现这个功能?

    回复 2最近活动 c