Rust 为什么可以';当外部寿命不同时,我是否将引用的一个解引用分配给另一个?

Rust 为什么可以';当外部寿命不同时,我是否将引用的一个解引用分配给另一个?,rust,lifetime,Rust,Lifetime,我想编写以下函数: fn foo<'a, 'b, 'c>(rr1: &'a mut &'c mut u32, rr2: &'b mut &'c mut u32) { *rr1 = *rr2; } 这使我认为,类型&'b mut&'c mut u32意味着参考链末端的u32仅在'b和'c相交时可用 对Rust的行为有什么正确的解释?为什么引用的引用会以这种方式而不是我认为的方式进行呢?您不能取消对a&'b mut&'c mut u32的引用并获

我想编写以下函数:

fn foo<'a, 'b, 'c>(rr1: &'a mut &'c mut u32, rr2: &'b mut &'c mut u32) {
    *rr1 = *rr2;
}
这使我认为,类型
&'b mut&'c mut u32
意味着参考链末端的
u32
仅在
'b
'c
相交时可用


对Rust的行为有什么正确的解释?为什么引用的引用会以这种方式而不是我认为的方式进行呢?

您不能取消对a
&'b mut&'c mut u32的引用并获得a
&'c mut u32
,因为:

  • &mut
    引用不是很容易复制的,因此您不能复制
    &c mut u32
    ;及
  • 您不能移出引用,因此也不能移动
    &'c mut u32
    (这将使外部引用悬空)
相反,编译器使用外部生存期
'b
重新编译
u32
。这就是为什么您会收到一条错误消息,即来自
rr2
的数据流入
rr1

如果允许编译
foo
,您可以使用它获取对同一
u32
的两个
&mut
引用,这是引用规则所禁止的:

let (mut x, mut y) = (10, 20);
let mut rx = &mut x;
let mut ry = &mut y;
foo(&mut rx, &mut ry); // rx and ry now both refer to y
std::mem::swap(rx, ry); // undefined behavior!
如果我要求“b”比“c”活得长,它就行了

因为
'c
必须比
'b
更长寿,如果您要求
'b
也比
'c
更长寿,那么
'c
=
'b
就可以了。更新后的签名与此等效:

fn foo<'a, 'b>(rr1: &'a mut &'b mut u32, rr2: &'b mut &'b mut u32)
这是因为
&
引用是
Copy
,因此
*rr2
不是重新箭头,实际上只是内部值的副本

有关更多信息,请阅读:



当没有明确的
'c:'b
绑定时,
'c
为什么会比
'b
长,这一点可能并不明显。原因是编译器假定类型
&'b mut&'c mut u32
格式正确。格式良好可能会变得复杂(请参阅),但在这种情况下,它只是意味着你不能拥有一个比它引用的东西(
'c
)有效时间更长的引用(
'b
)。

我一直在寻找隐式重新箭头的引用链接。你有吗?Rust参考文献中似乎根本没有提到它,但“因为隐式的重新开发”是近年来大量问题的答案。@SvenMarnach不幸的是,如果我有一个,我会链接到它(我可能也会有一些旧的答案需要更新!)我也不认为它在Nomicon中。
fn foo<'a, 'b>(rr1: &'a mut &'b mut u32, rr2: &'b mut &'b mut u32)
fn foo<'a, 'b, 'c>(rr1: &'a mut &'c u32, rr2: &'b mut &'c u32) {
    *rr1 = *rr2;
}