2017-12-29 57 views
1

의 내가 소수와 힘의 벡터 있다고 가정 해 봅시다 :`& (& usize, & u32)`와 같은 패턴과 어떻게 일치합니까?

let mut primes: Vec<usize> = ...; 
let mut powers: Vec<u32> = ...; 

그것은 사실 primes.len() == powers.len() 즉. ,

primes.iter().zip(powers) 
    .filter(|(p, power)| power > 0) 
    .map(|(p, power)| p) 
    .collect::<Vec<usize>>() 

컴파일러가 많이 불평 :

는 I (이 코드는 적절한 심판 및 derefs 누락 된 경우), 사용자에 0의 대응하는 전력 값이 소수의 목록을 반환하고 싶은 당신이 상상할 수도 있듯이. 특히 filter&(&usize, &u32) 유형의 인수를 받고 있지만 패턴 일치에서 올바르게 참조 해제되지 않았습니다. 컴파일러에서 제안하는 다양한 패턴 (예 : &(&p, &power), 나에게 가장 의미가있는 패턴)을 시도했지만 운이 없었습니다. power > 0 비교없이 문제를 비교할 수 있도록 패턴 일치를 올바르게 수행하고 결국 Vec<usize>을 수집 할 수 있습니까? 작동

답변

2
primes.iter().zip(powers) 

iter() 참조로 반복, 그래서 당신은 소수를위한 &usize 요소를 얻을. OTOH .zip()은 소유 값을 반복하는 .into_iter()을 호출하므로 능력은 u32이며이 반복자는 (&usize, u32) 이상의 반복을 결합합니다. 기술적으로, 이러한 혼합 유형을 반복하는 데는 아무런 문제가 없지만, 모순은 혼란 스러울 수 있습니다. 소수점에 .into_iter() 또는 .iter().cloned()을 사용하여 참조를 피하거나 .zip(powers.iter())을 호출하여 참조 용으로 사용할 수 있습니다.

두 번째 것은 .filter()는 (그것은 단지 그들에 "보이는"이후) 참조 &(_,_)으로 항목을 취하고, (그것을 변경하고 반환 할 수 있습니다) 소유의 값 (_,_)에 의해 .map() 것입니다. 정수 같은 작은 값의 경우

, 당신은 일반적으로이 같은이 방법을 사용하십시오 :

.filter(|by_ref| { 
    let item = *by_ref; 
}) 
: 폐쇄의 구문은, |pattern: type| 것을

.filter(|&item| …) 
.map(|item| …) 

참고 &item 위의 예에서, 그래서에 해당합니다

1

: 또한 참고로 소자를 얻을 powers.iter() 사용

fn main() { 
    let primes: Vec<usize> = vec![2, 3, 5, 7]; 
    let powers: Vec<u32> = vec![2, 2, 2, 2]; 

    let ret = primes.iter().zip(powers.iter()) 
      .filter_map(|(p, pow)| { // both are refs, so we need to deref 
       if *pow > 0 { 
        Some(*p) 
       } else { 
        None 
       } 
      }) 
      .collect::<Vec<usize>>(); 

    println!("{:?}", ret); 
} 

참고. 두 이터레이터에서 모두 cloned()을 사용하고 값을 사용할 수도 있습니다.