2014-10-10 3 views
3

가이 코드를 실행하려고 역 참조 포인터 밖으로 이동할 수 없습니다 문제.

+2

거기에 사용 된 다른 방법이나 간단한 예제를 컴파일하고 확인할 수 있도록 전체 struct/impl 블록을 사용할 수 있습니까? (바람직하게는 플레이 북에 붙여 넣기)? – snf

답변

10

귀하의 문제는 을 수락하고 실제로는 Option<&Node>을 수락하고 Option<&Node>도 반환해야합니다. 전화 사이트도 적절하게 변경해야합니다.

여기에 대한 설명이 있습니다. Box<T>은 힙 할당 상자입니다. 값 의미를 따른다 (즉, 평 균한 T처럼 동작한다. 단, 소멸자가 연관되어 항상 이동되고 결코 복사되지 않는다). 따라서 단지 Box<T>을 함수로 전달하면 값의 소유권을 포기하고 으로 이동시키는 것을 의미합니다. 그러나, 그것은 당신이 정말로 원하는 것이 아니며 여기서도 할 수 없습니다. get_right() 함수는 기존 구조 만 쿼리하므로 소유권이 필요하지 않습니다. 소유권이 필요 없으면 참고 문헌이 답입니다. 또한, self.min은 빌려준 포인터 인 self을 통해 액세스되기 때문에 self.min을 함수로 옮기는 것은 불가능합니다. 그러나 빌린 데이터에서 벗어날 수는 없으며 컴파일러가 제공하는 기본적인 안전 보장 중 하나입니다.

은 이런 식으로 get_right() 정의를 변경

:

fn get_right(e: Option<&Node>) -> Option<&Node> { 
    e.and_then(|n| n.right.as_ref().map(|r| &**r)) 
} 

그런 다음 println!() 호출이 변경되어야합니다

여기
println!("{}", get_right(self.min.map(|r| &**r)) 

여기에서 발생하는 것입니다. Option<Box<Node>>에서 Option<&Node>을 얻으려면 원래의 Option 내부에 "변환"을 적용해야합니다. 정확히 그 방법은 map()입니다. 그러나 map()은 목표 값을 취합니다. 이는 Box<Node>을 클로저로 이동시키는 것을 의미합니다. 그러나 Node 만 빌리기를 원하므로 이 작동하려면 먼저 Option<Box<Node>>에서 Option<&Box<Node>>으로 이동해야합니다.

Option<T>은 해당 대상을 참조로 사용하고 Option<&T>이라는 가능한 내부 참조를 반환하는 메서드를 가지고 있습니다. 우리의 경우에는 Option<&Box<Node>>이 될 것입니다. 이제이 값은 참조가 포함되어 있고 참조가 원래 값에 영향을주지 않고 자유롭게 이동할 수 있기 때문에 안전하게 map() 페달 오버가 될 수 있습니다.

다음으로 map(|r| &**r)Option<&Box<Node>>에서 Option<&Node>으로의 변환입니다. 클로저 인수는 옵션의 내부에 적용됩니다. 그렇지 않으면 None이 전달됩니다. &**r은 밖으로 읽어야합니다 : &(*(*r)), 즉, 먼저 &Box<Node>을 역 참조하고 Box<Node>을 얻은 다음 후자를 참조하여 Node을 얻은 다음 참조를 가져와 결국 &Node이됩니다. 이러한 참조/참조 취소 작업이 병치되어 있기 때문에 이동/복사가 필요하지 않습니다. 따라서 Node, Option<&Node>에 대한 참조가 있습니다.

비슷한 현상이 get_right() 함수에서 발생하는 것을 볼 수 있습니다. 그러나 새로운 방법 인 and_then()이 호출됩니다. 그것은 당신이 처음에 get_right()에 쓴 것과 동일합니다 : 목표는 None 경우, 그것은 None 반환, 그렇지 않으면 인수로 전달 Option -returning 폐쇄의 결과 반환

fn and_then<U>(self, f: |T| -> Option<U>) -> Option<U> { 
    match self { 
     Some(e) => f(e), 
     None => None 
    } 
} 

내가 강력하게 제안 the official guide를 읽고 어떤 이것이 Rust 언어의 기초이며, Rust와 생산적으로되기 위해서는 그것을 이해하는 것이 매우 중요하기 때문에 소유권과 차용이 무엇인지와 어떻게 사용하는지 설명합니다.