2016-06-01 3 views
2

내가 뭘하려고 같은 벡터에 밀어 : 나는 last()를 호출 할 때, 그것은 반환을 이해벡터의 마지막 요소를 확인하고

enum Test { 
    Value1, 
    Value2, 
    Value3 
} 

fn main() { 
    let mut test_vec: Vec<Test> = Vec::new(); 
    test_vec.push(Test::Value2); 

    if let Some(last) = test_vec.last() { 
     test_vec.push(*last); 
    } 
    //Wanted output: vector with [Test::Value2, Test::Value2] 
} 

Option<&Test> 그래서이 test_vec을 빌려 if-let 블록의 끝까지.

if let Some(last) = test_vec.last().map(|v| v.clone()) { 
    test_vec.push(*last); 
} 

//and 

let last = test_vec.last().unwrap().clone(); 
test_vec.push(*last); 

답변

2

차용 검사기가 포함 된 유형을 식별하는 데 유용 할 수 있습니다 불평 이유를 알아 내려고.

아웃 입력하면 :

let _:() = test_vec.last().map(|v| v.clone()); 

당신이 ()core::option::Option<&Test> 동일한 유형 아니라는 것을 불평 오류가 발생합니다.

무슨 일 이니? 매우 간단하게 말해서 &Test을 복제하면 &Test이되고 Option<&Test>.map(|v| v.clone())을 호출하면 Option<&Test>이됩니다. 분명히, 그것은 여전히 ​​빌려옵니다.

let _:() = test_vec.last().unwrap().clone(); 

오류가 ()&Test 동일한 유형 아니라는 것을 불평 얻을 : 당신이 밖으로 입력하면

같은 문제가, 다음 시도 발생합니다.

Option<&Test>에서 unwrap을 호출하면 &Test이되며 &Test에 복제됩니다.


그래서, 문제는를 역 참조 의 부족이다. 당신은 Some(last)에서 차입 test_vec을 방지하기 위해, 이전 역 참조 할 필요가 : Testclone를 구현하지 않기 때문에

if let Some(last) = test_vec.last().map(|v| (*v).clone()) { 
    test_vec.push(last); 
} 

물론,이 작동하지 않습니다. 고정되면 (#[derive(Clone)]에 의해) 컴파일됩니다.

참조로 복제하는 등의 일반적인 요구이므로 Option (및 Iterator)이 cloned 전화의 전용 방법이있다 :

if let Some(last) = test_vec.last().cloned() { 
    test_vec.push(last); 
} 
5

Option<&T>에서 Option<T>을 생산하면 Option::cloned를 호출 할 수 있습니다 차용 문제를 해결하려면

내가 성공하지 않고 다음을 시도했다. 이렇게하려면 TestClone을 구현해야합니다. 당신은 derive를 사용 Test에 대한 Clone을 구현할 수 있습니다

// To allow assert_eq, we also derive Debug and PartialEq 
#[derive(Debug, PartialEq, Clone)] 
enum Test { 
    Value1, 
    Value2, 
    Value3 
} 

fn main() { 
    let mut test_vec = Vec::new(); 
    test_vec.push(Test::Value2); 

    if let Some(last) = test_vec.last().cloned() { 
     test_vec.push(last); 
    } 

    assert_eq!(vec![Test::Value2, Test::Value2], test_vec); 
} 
관련 문제