问题描述
我无法在我认为可以的地方借钱。我将问题归结为这种情况:
struct A<'a> {
borrow: &'a mut u8,}
fn does_nothing<'b,'c>(a: &'b mut A<'c>) {
a.borrow = a.borrow;
}
error[E0623]: lifetime mismatch
--> src/lib.rs:6:16
|
5 | fn does_nothing<'b,'c>(a: &'b mut A<'c>) {
| -------------
| |
| these two types are declared with different lifetimes...
6 | a.borrow = a.borrow;
| ^^^^^^^^ ...but data from `a` flows into `a` here
似乎a.borrow
具有'b
和'c
的交集,因此不能保证仍然具有生存期'c
。
我对此没有任何实际问题,可以通过使两个生命周期相同来解决此问题,但是为什么这不借用检查呢?
我有三个函数,它们非常相似,但是我很难知道哪个函数可以编译,而非编译函数会给出哪些错误。
简单的通用函数:
fn only_borrow<T>(a: &mut T) {
*a = *a;
}
导致错误:
error[E0507]: cannot move out of `*a` which is behind a mutable reference
--> src/lib.rs:2:10
|
2 | *a = *a;
| ^^ move occurs because `*a` has type `T`,which does not implement the `copy` trait
包含额外的间接级别会更改错误
fn only_borrow_double<T>(a: &mut &mut T) {
*a = *a;
}
error[E0623]: lifetime mismatch
--> src/lib.rs:2:10
|
1 | fn only_borrow_double<T>(a: &mut &mut T) {
| -----------
| |
| these two types are declared with different lifetimes...
2 | *a = *a;
| ^^ ...but data from `a` flows into `a` here
远离隐含的寿命可以修复错误:
fn working_double<'b,T>(a: &'b mut &'b mut T) {
*a = *a;
}
解决方法
您必须查看自己的一生'b
和'c
:
-
&'b mut ...
意味着您拥有一个在“时间”'b
内有效且有效的参考。 -
A<'c>
表示您拥有一个对'c
有效且有效的对象。
您没有的是这两个生命周期之间的特定关系。编译器唯一可以推断的是,由于A<'c>
位于&'b
的后面,因此'c
的生存期必须长于'b
,也就是说,只要'b
有效,那么{ 'c
。不过,至关重要的是,并非相反。
如您所示,编译器要求'b
和'c
具有相同的生存期。
为什么会这样?
让我们看看我们的可能性:
-
'c
和'b
没有关系:很容易看出,没有任何关系,编译器无法保证有关A.borrow
中内容的任何保证,因此不允许它。 -
'c
严格超过'b
,也就是说,某些地方'c
有效'b
不是:
在a.borrow = a.borrow
的生存期内,a
成为'b
的借入。 This answer explains why that happens。但是,这意味着a
现在取决于'b
的生存期,在a
有效的某些时间内无效(因为a
的生存期为{{ 1}})。这给出了错误。 -
'c
的生存期完全超过'b
:如果我们有这种关系,它可能会起作用。重新借贷将是有效的,因为我们的生存期('c
)比我们要求的('b
)更长。但是,编译器已经在幕后推断出'c
。因此,添加此生存期意味着两个生存期变得相等,然后我们回到起点:
'c: 'b