여러 개의 가변 참조로 인해 구조체의 멤버를 자신에게 할당 할 수없는 이유는 무엇입니까? [복제]
내가 할 수 있다고 생각했던 곳에서 빌릴 수 없습니다. 이 경우에 문제를 줄였습니다.
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;
}
답변
Emoun
당신은 당신의 생애를 살펴 걸릴해야합니다 '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
. 이 대답은 그 이유를 설명합니다 . 그러나 이것은a
이제'b
수명에 따라 달라 지며, 일부 시간 동안 유효하지 않은a
것은 유효합니다 (a
수명이 있기 때문에'c
). 이것은 오류를 제공합니다.'b
엄격히 오래 살아남습니다'c
: 우리가이 관계를 가졌다면 그것은 효과가있을 것입니다. 요청한 것보다 "더 큰"수명 ('b
)을 얻으므로 재차 입은 유효합니다'c
. 그러나 우리는 이미'c: 'b
뒤에서 컴파일러에 의해 추론되었습니다. 따라서이 수명을 추가하면 두 수명이 동일 해지며 시작된 곳으로 돌아갑니다.
struct A<'a> {
borrow: &'a mut u8,
}
/// We add the relation 'b: 'c
fn does_nothing<'b: 'c, 'c>(a: &'b mut A<'c>) {
a.borrow = a.borrow;
}