Rust if let=,似乎泄漏了Ubuntu Linux上的RHS函数结果,这是预期的吗?

Rust if let=,似乎泄漏了Ubuntu Linux上的RHS函数结果,这是预期的吗?,rust,scope,Rust,Scope,我有下面的代码,它在Mac和Windows上运行良好,但在Ubuntu Linux上运行不好。死机出现在借用位置,指示服务器已被永久借用。这似乎表明,if泄露了服务器借用,这是我没料到的。然后我将3ifs包装在{}中,Ubuntu Linux不再恐慌。我认为这证明了,if泄露了借款。我错了吗?这是预期的吗?或者,生锈和原子参考电池是否还有其他我不知道的事情 AtomicRefCell来自 下面是一个完整的例子来说明这个问题主.rs: use atomic_refcell::AtomicRefCe

我有下面的代码,它在Mac和Windows上运行良好,但在Ubuntu Linux上运行不好。死机出现在
借用位置
,指示
服务器
已被永久借用。这似乎表明,
if
泄露了
服务器
借用,这是我没料到的。然后我将3
if
s包装在
{}
中,Ubuntu Linux不再恐慌。我认为这证明了,
if
泄露了借款。我错了吗?这是预期的吗?或者,生锈和原子参考电池是否还有其他我不知道的事情

AtomicRefCell
来自

下面是一个完整的例子来说明这个问题<代码>主.rs:

use atomic_refcell::AtomicRefCell;

#[allow(non_upper_case_globals)]
static server: AtomicRefCell<Server> = AtomicRefCell::new(Server {
    value: ServerField::Uninitialized,
});

#[derive(Debug)]
pub struct Server {
    value: ServerField,
}

#[derive(Debug)]
enum ServerField {
    Uninitialized,
    Value(usize),
}

fn start() {
    server.borrow_mut().value = ServerField::Value(41);
}

fn stop() {
    // enclose this in a scope to not panic
    let borrow = &server.borrow();
    println!("value is {:#?}", borrow.value);
    drop(borrow);
    // end scope
    let mut s = server.borrow_mut();
    s.value = ServerField::Uninitialized;
}

fn main() {
    println!("Hello, world!");
    start();
    stop();
}
#[cfg(test)]
pub mod tests {
    use super::*;
    #[test]
    fn test() {
        start();
        stop();
    }
}
在本例中,
如果let
与&server.borrow().value的RHS一起使用,它在Mac上不会死机,但在Ubuntu Linux上可能死机(我没有Linux框,也没有上传到
GitHub
并创建工作流)。然而,这反映了我在
GitHub
上的代码,它在工作流中显示了这种行为

use atomic_refcell::AtomicRefCell;

#[allow(non_upper_case_globals)]
static server: AtomicRefCell<Server> = AtomicRefCell::new(Server {
    value: ServerField::Uninitialized,
});

#[derive(Debug)]
pub struct Server {
    value: ServerField,
}

#[derive(Debug)]
enum ServerField {
    Uninitialized,
    Value(usize),
}

fn start() {
    server.borrow_mut().value = ServerField::Value(41);
}

fn stop() {
    if let ServerField::Value(val) = &server.borrow().value {
        println!("value is {:#?}", val);
    }
    let mut s = server.borrow_mut();
    s.value = ServerField::Uninitialized;
}

fn main() {
    println!("Hello, world!");
    start();
    stop();
}
#[cfg(test)]
pub mod tests {
    use super::*;
    #[test]
    fn test_start_stop() {
        start();
        stop();
    }
}
使用原子refcell::AtomicRefCell;
#[允许(非大写字母)]
静态服务器:AtomicRefCell=AtomicRefCell::新建(服务器{
值:ServerField::未初始化,
});
#[导出(调试)]
发布结构服务器{
值:ServerField,
}
#[导出(调试)]
枚举服务器字段{
未初始化,
价值(usize),
}
fn start(){
server.borrow_mut().value=ServerField::value(41);
}
fn停止(){
如果让ServerField::Value(val)=&server.borrow().Value{
println!(“值为{:#?}”,val);
}
让mut s=server.borrow_mut();
s、 value=ServerField::未初始化;
}
fn main(){
println!(“你好,世界!”);
start();
停止();
}
#[cfg(测试)]
pub-mod测试{
使用超级::*;
#[测试]
fn测试开始停止(){
start();
停止();
}
}

如果没有更多的上下文,很难确定问题的起因。哪个板条箱提供的是
AtomicRefCell
类型?是否确定在每个平台上执行相同的代码路径?添加了AtomicRefCell信息和链接。我很确定这三个版本都运行相同的代码路径,因为我所做的更改是唯一的更改,它“修复”了Ubuntu Linux。这是一个解决方案,而不是解决根本问题的修复方案,但是您能否尝试先借用服务器,然后在每个if语句中使用相同的借用?e、 g.
让s=server.borrow();如果让ServerField::Executor(…)=。。。{ ... }; 下降(s);;让mut s=server.borrow_mut()当然可以,但除了性能,我不希望它与我在{}中包装ifs所创建的范围有任何不同。然而,这确实提出了一个问题。编译器是否进行了一些优化,识别出相同的借用代码并将其取出,忘记添加删除。这是出乎意料的。它引起了恐慌。我不得不把借来的东西包起来,放进一个示波器里防止它。这似乎表明drop(借用)正在延迟drop,而退出作用域时它不会延迟drop。
use atomic_refcell::AtomicRefCell;

#[allow(non_upper_case_globals)]
static server: AtomicRefCell<Server> = AtomicRefCell::new(Server {
    value: ServerField::Uninitialized,
});

#[derive(Debug)]
pub struct Server {
    value: ServerField,
}

#[derive(Debug)]
enum ServerField {
    Uninitialized,
    Value(usize),
}

fn start() {
    server.borrow_mut().value = ServerField::Value(41);
}

fn stop() {
    // enclose this in a scope to not panic
    let borrow = &server.borrow();
    println!("value is {:#?}", borrow.value);
    drop(borrow);
    // end scope
    let mut s = server.borrow_mut();
    s.value = ServerField::Uninitialized;
}

fn main() {
    println!("Hello, world!");
    start();
    stop();
}
#[cfg(test)]
pub mod tests {
    use super::*;
    #[test]
    fn test() {
        start();
        stop();
    }
}
[dependencies]
atomic_refcell = "0.1"
use atomic_refcell::AtomicRefCell;

#[allow(non_upper_case_globals)]
static server: AtomicRefCell<Server> = AtomicRefCell::new(Server {
    value: ServerField::Uninitialized,
});

#[derive(Debug)]
pub struct Server {
    value: ServerField,
}

#[derive(Debug)]
enum ServerField {
    Uninitialized,
    Value(usize),
}

fn start() {
    server.borrow_mut().value = ServerField::Value(41);
}

fn stop() {
    if let ServerField::Value(val) = &server.borrow().value {
        println!("value is {:#?}", val);
    }
    let mut s = server.borrow_mut();
    s.value = ServerField::Uninitialized;
}

fn main() {
    println!("Hello, world!");
    start();
    stop();
}
#[cfg(test)]
pub mod tests {
    use super::*;
    #[test]
    fn test_start_stop() {
        start();
        stop();
    }
}