简体   繁体   English

Rust 所有权问题

[英]Rust ownership issues

I'm quite new to Rust, I'm mainly a C#, javascript and python developer, so I like to approach things in a OOP way, however I still can't wrap my head around ownership in rust. I'm quite new to Rust, I'm mainly a C#, javascript and python developer, so I like to approach things in a OOP way, however I still can't wrap my head around ownership in rust. Especially when it comes to OOP.尤其是涉及到 OOP 时。

I'm writing a TCP server.我正在写一个 TCP 服务器。 I have a struct that contains connections (streams) and I read the sockets asynchronously using the mio crate.我有一个包含连接(流)的结构,我使用 mio crate 异步读取了 sockets。 I understand what the error is telling me, but I have no clue how to fix it.我明白错误告诉我什么,但我不知道如何解决它。 I tried changing the read_message method into a function (without the reference to self), which worked, but the problem with this is that I'll need to access the connections and whatnot from the struct (to relay messages between sockets for example), so this workaround won't be plausible in later versions.我尝试将 read_message 方法更改为 function(不引用 self),这有效,但问题是我需要从结构访问连接和诸如此类的东西(例如,在 sockets 之间中继消息),所以这个解决方法在以后的版本中是不合理的。 Is there an easy fix for this, or is the design inherently flawed?有没有简单的解决方法,还是设计本身就有缺陷?

Here's a snippet that shows what my problem is:这是一个片段,显示了我的问题:

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!()
    } 
}

And the error I'm getting is the following:我得到的错误如下: 在此处输入图像描述

You are holding a mutable borrow on sock , which is part of self , at the moment you try to call self.read_message .在您尝试调用self.read_message的那一刻,您在sock上持有一个可变借用,这是self的一部分。 Since you indicated that read_message needs mutable access to all of self , you need to make sure you don't have a mutable borrow on sock anymore at that point.由于您指出read_message需要对所有self进行可变访问,因此您需要确保此时不再有可变借用sock

Fortunately, thanks to non-lexical lifetimes in Rust 2018, that's not hard to do;幸运的是,由于 Rust 2018 中的非词汇生命周期,这并不难做到; simply fetch sock inside the loop:只需在循环内获取sock

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

Assuming sock.read doesn't return anything that holds a borrow on sock , this should let the mutable borrow on sock be released before calling self.read_message .假设sock.read不返回任何持有sock借用的东西,这应该让sock上的可变借用在调用self.read_message之前被释放。 It needs to be re-acquired in the next iteration, but seeing as you're doing network I/O, the relative performance penalty of a single HashMap (?) access should be negligible.它需要在下一次迭代中重新获取,但是当您正在执行网络 I/O 时,单个HashMap (?) 访问的相对性能损失应该可以忽略不计。

(Due to lack of a minimal, compileable example, I wasn't able to test this.) (由于缺少最小的可编译示例,我无法对此进行测试。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM