用一个小例子来说明这个问题.以下内容进行了编译:

fn main() {
    let value: u32 = 15;
    let mut ref_to_value: &u32 = &0;
    fill_object(&mut ref_to_value, &value);
    println!("referring to value {}", ref_to_value);
}

fn fill_object<'a>(m: &mut &'a u32, v: &'a u32) {
    *m = v;
}

现在,下面给出了一个关于可变借入和不可变借入的编译时错误:

fn fill_object<'a>(m: &'a mut &'a u32, v: &'a u32) {
    *m = v;
}


fill_object(&mut ref_to_value, &value);
  |                 ----------------- mutable borrow occurs here
5 |     println!("referring to value {}", ref_to_value);
  |                                       ^^^^^^^^^^^^
  |                                       |
  |                                       immutable borrow occurs here
  |                                       mutable borrow later used here

为什么?我假设,因为我现在已经为ref_to_value的引用指定了生存期‘a,所以该可变引用现在覆盖了整个作用域(即main).

我想弄清楚该如何思考这件事.

推荐答案

你的直觉是正确的.用一生的时间,

fn fill_object<'a>(m: &'a mut &'a u32, v: &'a u32) {
  *m = v;
}

所有三个引用都需要存活相同的长度,所以如果v存活很长时间,那么可变引用也必须存活.这不是直观的行为,所以像这样把生命联系在一起通常是一个坏主意.如果您没有指定any个生存期,Rust会隐式地 for each 引用指定一个不同的生存期.因此,以下内容是等价的.

fn fill_object(m: &mut &u32, v: &u32)
fn fill_object<'a, 'b, 'c>(m: &'a mut &'b u32, v: &'c u32)

(注意:returned个值的推断生命周期稍微复杂一些,但在这里不起作用)

因此,您部分指定的生命周期 相当于

fn fill_object<'a>(m: &mut &'a u32, v: &'a u32);
fn fill_object<'a, 'b>(m: &'b mut &'a u32, v: &'a u32);

顺便说一句,由于多种原因,&mut &u32weird的类型.撇开u32是复制的事实不谈(因此,在泛型之外,获取不变的引用是无用的),可变引用to不变引用只是令人困惑的.我不确定你真正的用例是什么.如果这只是一个测试示例,那么当然可以.但如果这是您真正的程序,我建议您考虑是否可以使用fill_object(&mut u32, u32),如果您really需要嵌套引用,您可能会考虑让它更容易接受一个 struct .

struct MyIntegerCell<'a>(&'a u32);

外加一些说明为什么需要这样做的文档.然后你会有fill_object(&mut MyIntegerCell, u32)个左右的数字.

Rust相关问答推荐

程序退出后只写入指定管道的数据

收集RangeInclusive T到Vec T<><>

如何仅使用http机箱发送http请求?

铁 rust 干线无法使用PowerShell获取环境变量

这种获取-释放关系是如何运作的?

有没有办法指定只在Rust的测试中有效的断言?

当T不执行Copy时,如何返回Arc Mutex T后面的值?

对于已经被认为是未定义行为的相同数据,纯粹存在`&;[u32]`和`&;mut[u32]`吗?

如何修复数组中NewType导致的运行时开销

在Rust中声明和定义一个 struct 体有什么区别

为什么rustc会自动降级其版本?

Button.set_hexpand(false) 不会阻止按钮展开

中文优化标题:跳出特定循环并返回一个值

为什么这段 Rust 代码会在没有递归或循环的情况下导致堆栈溢出?

简单 TCP 服务器的连接由对等重置错误,mio 负载较小

从 Axum IntoResponse 获取请求标头

如何在 Rust 中返回通用 struct

在 Rust 中退出进程

为什么这个 Trait 无效?以及改用什么签名?

这个 match 语句的默认值应该是什么,还有一种方法可以解开 Some case (chess in rust)