为什么对已删除对象的可变引用仍算作可变引用? [英] Why does a mutable reference to a dropped object still count as a mutable reference?

查看:110
本文介绍了为什么对已删除对象的可变引用仍算作可变引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个简化的示例:

struct Connection {}

impl Connection {
    fn transaction(&mut self) -> Transaction {
        Transaction { conn: self }
    }
}

struct Transaction<'conn> {
    conn: &'conn Connection,
}

impl<'conn> Transaction<'conn> {
    fn commit(mut self) {}
}

fn main() {
    let mut db_conn = Connection {};

    let mut trans = db_conn.transaction(); //1
    let mut records_without_sync = 0_usize;
    const MAX_RECORDS_WITHOUT_SYNC: usize = 100;
    loop {
        //do something
        records_without_sync += 1;
        if records_without_sync >= MAX_RECORDS_WITHOUT_SYNC {
            trans.commit();
            records_without_sync = 0;
            trans = db_conn.transaction(); //2
        }
    }
}

编译器在 1 2 上报告了两个可变借位,但事实并非如此.由于trans.commit()按值取self,因此将删除trans,因此在点 2 处应该没有可变的引用.

The compiler reports two mutable borrows at 1 and 2, but that is not the case. Since trans.commit() takes self by value, trans is dropped, so by point 2 there should be no mutable references.

  1. 为什么编译器在 2 上看不到没有可变引用?
  2. 我该如何修正代码,而又保持相同的逻辑?
  1. Why can the compiler not see that at 2 there are no mutable references?
  2. How can I fix the code, leaving the same logic?

推荐答案

非词汇生命周期时,您的原始代码可以工作已启用:

Your original code works when non-lexical lifetimes are enabled:

#![feature(nll)]

struct Connection {}

impl Connection {
    fn transaction(&mut self) -> Transaction {
        Transaction { conn: self }
    }
}

struct Transaction<'conn> {
    conn: &'conn Connection,
}

impl<'conn> Transaction<'conn> {
    fn commit(self) {}
}

fn main() {
    let mut db_conn = Connection {};

    let mut trans = db_conn.transaction();
    let mut records_without_sync = 0_usize;
    const MAX_RECORDS_WITHOUT_SYNC: usize = 100;
    loop {
        //do something
        records_without_sync += 1;
        if records_without_sync >= MAX_RECORDS_WITHOUT_SYNC {
            trans.commit();
            records_without_sync = 0;
            trans = db_conn.transaction();
        }
    }
}

非词法生存期可提高借阅检查器的精度.编译器变得更加智能,现在可以证明更多程序对内存安全.

Non-lexical lifetimes improve the precision of the borrow checker. The compiler has become smarter and it is now able to prove that more programs are memory safe.

这篇关于为什么对已删除对象的可变引用仍算作可变引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆