Rust 所有权问题

Posted

技术标签:

【中文标题】Rust 所有权问题【英文标题】:Rust ownership issues 【发布时间】:2021-01-29 16:10:51 【问题描述】:

我对 Rust 很陌生,我主要是 C#、javascript 和 python 开发人员,所以我喜欢以 OOP 方式处理事情,但是我仍然无法理解 rust 的所有权。尤其是在 OOP 方面。

我正在编写一个 TCP 服务器。我有一个包含连接(流)的结构,我使用 mio crate 异步读取套接字。我明白错误告诉我什么,但我不知道如何解决它。我尝试将 read_message 方法更改为一个函数(没有对 self 的引用),它起作用了,但问题是我需要从结构访问连接和诸如此类的东西(例如,在套接字之间中继消息),所以这个解决方法在以后的版本中是不合理的。是否有简单的解决方法,或者设计本身存在缺陷?

这是一个显示我的问题的 sn-p:

let sock = self.connections.get_mut(&token).unwrap();
loop 
    match sock.read(&mut msg_type) 
        Ok(_) => 
            self.read_message(msg_type[0], token);
        
    


fn read_message(&mut self, msg_type: u8, token: Token) 
    let sock = self.connections.get_mut(&token).unwrap();
    let msg_type = num::FromPrimitive::from_u8(msg_type);
    match msg_type 
        Some(MsgType::RequestIps) => 
            let decoded: MsgTypes::Announce = bincode::deserialize_from(sock).unwrap();
            println!("Public Key: ", decoded.public_key);
        
        _ => unreachable!()
     

我得到的错误如下:

【问题讨论】:

【参考方案1】:

您在sock 上持有一个可变借用,它是self 的一部分,此时您尝试调用self.read_message。由于您指出 read_message 需要对所有 self 进行可变访问,因此您需要确保此时您不再对 sock 进行可变借用。

幸运的是,感谢 Rust 2018 中的非词法生命周期,这并不难做到;只需在循环内获取sock

loop 
    let sock = self.connections.get_mut(&token).unwrap();
    match sock.read(&mut msg_type) 
        Ok(_) => 
            self.read_message(msg_type[0], token);
        
    

假设sock.read 没有返回任何在sock 上持有借用的东西,这应该让sock 上的可变借用在调用self.read_message 之前被释放。它需要在下一次迭代中重新获取,但鉴于您正在执行网络 I/O,单个 HashMap (?) 访问的相对性能损失应该可以忽略不计。

(由于缺少可编译的最小示例,我无法对此进行测试。)

【讨论】:

非常感谢。尽管缺乏适当的例子,但您完全理解我的问题。

以上是关于Rust 所有权问题的主要内容,如果未能解决你的问题,请参考以下文章

新手眼中的 Rust 所有权规则

Rust 所有权

如何将值的所有权从 Rust 转移到 C 代码?

Rust 如何知道哪些类型拥有资源?

怎样才能强制 Rust 获得分配的内存的所有权,而不是通过其安全方法分配的内存?

RUST 语言特性之所有权