Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 如何安全地使用由唯一ID表示的外部数据?_Rust - Fatal编程技术网

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

Rust 如何安全地使用由唯一ID表示的外部数据?,rust,Rust,我可能希望在Rust中与许多外部系统(网络API、FFI到遗留C库等)进行交互,它们使用数字ID表示远程资源。这些ID通常有一个隐含的上下文,在该上下文中它们是有效的,并且在程序持有它们时可能会过期 我习惯于在其他编程语言中处理这个问题,但是在阅读了Rust书籍(特别是在讨论字符串索引的地方)之后,我觉得避免在我的程序中直接公开这些ID会更清晰、更安全,因为它们依赖于上下文,并且不能保证它们在将来是有效的Rust中是否存在允许我安全地与ID表示的远程资源交互的模式? 考虑一个我尝试使用的特定AB

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

我习惯于在其他编程语言中处理这个问题,但是在阅读了Rust书籍(特别是在讨论字符串索引的地方)之后,我觉得避免在我的程序中直接公开这些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.
   ...
}
//窗口表示为每个连接的唯一ID。
类型WindowId=u64;
///从显示服务器获取窗口列表。
fn get_windows()->Vec{
//对display server进行外部调用以获取窗口ID列表。
...
}
///等待显示服务器发送的下一个事件。
fn get_event()->event{
//块,直到我们收到一个事件,其中一个事件可以指示
//窗口已被销毁,不再有效。
...
}
///使用窗口获取数据的函数示例。
fn获取窗口尺寸(窗口:WindowId)->(u32,u32){
//对display server进行外部调用,以询问
//由提供的WindowId引用的窗口。
...
}
///使用窗口修改数据的函数示例。
fn设置窗口尺寸(窗口:窗口ID,x:u32,y:u32){
//对display server进行外部调用以设置的维度
//由提供的WindowId引用的窗口。
...
}
此代码要求我们使用
WindowId
s引用窗口资源,但值得注意的是,如果:

  • 我们的程序调用一个例如
    destroy\u Window()
    函数来破坏窗口
  • 窗口被拥有它的远程进程/客户端破坏
  • 我们的客户端失去连接,使可能仍然存储的所有
    WindowId
    s无效
  • 在我的案例中,这些场景中的每一个都被认为是正常的行为,并期望由客户机处理。这使得直接使用
    WindowId
    时,如果不使用某种方法将作用域显式编码到其中,就会感到脆弱。例如,存储
    WindowId
    的程序的其他部分可能会突然发现引用的相关窗口无效,并且可能需要检测和处理这种情况


    这感觉可能会很快变得一团糟!在这些约束条件下,我是否可以安全地与生锈的窗口进行交互,或者我是否需要直接处理
    WindowId
    s?

    根据您的描述,结构可能适合这里,因为用户似乎从不需要id的实际数值

    struct WindowId(u64);
    
    这并不能解决ID失效的问题。 要解决第1点,您可以使导致Id无效的函数使用该Id(按值获取),前提是上述新类型结构没有派生副本,并且如果合理,也没有实现克隆

    impl WindowId{
    fn(自我毁灭){
    /*…剪断*/
    }
    }
    
    这仍然保留第2点和第3点,最好的选择可能是所有通过其ID访问窗口的操作都是可失败的,例如通过返回

    impl WindowId{
    fn大小(自身)->结果{
    /*…剪断*/
    }
    }
    
    为什么不创建一个
    结构窗口{id:u64}
    并向其中添加方法?至于无效,在客户端上下文中,当窗口ID变为无效时,所需的行为到底是什么?在某些上下文中(如处理其他事件时),窗口将被视为有效,但一般来说,如果窗口ID变为无效,则应丢弃对它的任何引用。@malwrar您提到的“隐含上下文”,对于
    窗口
    s,您的案例中是否有一个?如果是这样的话,就有可能简化Skgland的答案,只使用一个初始方法返回
    结果
    。我还不清楚这一点,比如说客户端有一个
    窗口
    窗口ID
    结构。一旦窗口失效,如果客户端尝试使用该结构会发生什么?当您说“应该丢弃它”时,当窗口ID无效时,当前正在调用某个窗口API的代码会发生什么情况?另外,客户端如何通过轮询“发现”失效?我担心我需要让每个方法都返回一个结果,但我认为这可能是解决方案。在接受这个答案之前,我会先把它打开一点。