gpt4 book ai didi

rust - 如何安全地使用由唯一 ID 表示的外部数据?

转载 作者:行者123 更新时间:2023-12-03 11:26:49 25 4
gpt4 key购买 nike

我可能希望在 Rust 中与之交互的许多外部系统(网络 API、FFI 到遗留 C 库等)使用数字 ID 来表示远程资源。这些 ID 通常具有隐含的上下文,在该上下文中它们是有效的,并且可以在程序持有它们时过期。

我习惯用其他编程语言处理这个问题,但在阅读 Rust 书(特别是 this chapter ,其中讨论了字符串索引)之后,我觉得避免直接暴露这些 ID 会更清晰、更安全在我的程序中,因为它们依赖于上下文并且不能保证它们在将来有效。 Rust 中是否有任何模式允许我安全地与由 ID 表示的远程资源交互?

考虑一个我尝试使用的特定 ABI 的简化示例来演示该问题:

// Windows are represented as a unique ID per connection.
type WindowId = u64;

/// Fetches a list of Windows from the display server.
fn get_windows() -> Vec<WindowId> {
// Makes an external call to display server to get a list of Window IDs.
...
}

/// Wait for the next event sent by the display server.
fn get_event() -> Event {
// Blocks until we receive an event, one of which can indicate that a
// Window has been destroyed and is no longer valid.
...
}

/// Example of a function that uses a Window to fetch data.
fn get_window_dimensions(window: WindowId) -> (u32, u32) {
// Makes an extermal call to display server to ask for the dimensions of
// the window referenced by the provided WindowId.
...
}

/// Example of a function that uses a Window to modify data.
fn set_window_dimensions(window: WindowId, x: u32, y:u32) {
// Makes an extermal call to display server to set the dimensions for
// the window referenced by the provided WindowId.
...
}

此代码要求我们使用 WindowId 引用 Window 资源,但值得注意的是,如果出现以下情况,这些 ID 可能会变得无效:

  1. Window 被我们的程序调用例如destroy_window() 函数。
  2. Window 被拥有它的远程进程/客户端销毁。
  3. 我们的客户端失去连接,使所有可能仍存储的 WindowId 失效

在我的案例中,这些场景中的每一个都被认为是正常行为,并且应该由客户处理。这使得 WindowId 在没有明确编码范围的情况下直接使用时感觉很脆弱。例如,存储 WindowId 的程序的其他部分可能会突然发现引用的关联 Window 无效,并且需要以某种方式检测和处理这种情况。

这感觉很快就会变得非常困惑!在这些约束下,有什么方法可以让我在 Rust 中安全地与 Windows 交互,还是我需要直接处理 WindowId

最佳答案

根据您的描述,似乎是一个 new type idiom struct 在这里可能是合适的,因为用户似乎永远不需要 id 的实际数值。

struct WindowId(u64);

这并不能解决 ID 失效的问题。要解决第 1 点,您可以使导致 Id 无效的函数使用 Id(按值获取),假设上面提到的新类型结构不派生 Copy 并且如果合理的话不实现 Clone。

impl WindowId {
fn destroy(self){
/* .. snip .. */
}
}

这仍然留下第 2 点和第 3 点,最好的选择可能是所有通过其 ID 访问窗口的操作都是可失败的,例如通过返回 Result .

impl WindowId {
fn size(&self) -> Result<(u32, u32), WindowError> {
/* .. snip .. */
}
}

关于rust - 如何安全地使用由唯一 ID 表示的外部数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65544739/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com