문제는 클로저를 두 번 호출 할 가능성이 있습니다. 첫 번째 실행에서 캡처 된 변수 num
은 inner
으로 이동됩니다. 즉, 클로저의 환경 밖으로 이동합니다. 그런 다음 두 번째 호출에서 num
이 있던 위치가 이제는 유효하지 않게되고 (메모리가 이동 된 이후에) 메모리 안전이 손상됩니다. 잘못된 하나, 하나가 inner
전화로 빌린 포인터 뒤에서 self.num
를 이동하려고 :
구체적으로, 하나는 (약)
struct Closure { // stores all the captured variables
num: ~int
}
impl Closure {
fn call(&self, x: int) -> int {
// valid:
*self.num + x
// invalid:
// *inner(self.num) + x
}
}
는 희망이 그것을 만드는 명확로 폐쇄 간주 할 수 있습니다 (그 이후에는 완전히 num
필드와의 연결이 끊어집니다). 가능한 경우 self
은 유효하지 않은 상태로 남습니다. 예를 들어 self.num
의 소멸자가 호출되어 메모리를 해제합니다 (메모리 안전을 위반 함). 이것의
한 해상도로 위 call
의 유형을 조정 (그것의 가장 기본적인에서)가 찬성 제거 할 수 있기 때문에, 구현하지만 컴파일러 플래그 뒤에 숨겨져있다 "기능을 한 번"입니다 fn call(self, x: int)
, 즉 클로저가 self
으로 이동하면 (즉, call
이 self
및 해당 필드를 소유하고 있기 때문에) 환경 밖으로 이동할 수 있고 함수가 정적으로 한 번만 호출 될 수 있다는 것을 의미합니다 *.
* 클로저의 환경이 소유권을 이전하지 않는 경우 (예 : 그것이 struct Env { x: int }
인 경우.
정답이 아니므로 댓글로 추가하겠습니다. https://github.com/mozilla/rust/wiki/Doc-under-construction-FAQ –