2016-06-02 1 views
2

Playpen변경할 수있는 참조를 사용하여 값을 이동할 수 있습니까?

pub trait Skip<I: Iterator> { 
    fn skip(&mut self, steps: usize); 
} 

impl<I: Iterator> Skip<I> for I { 
    fn skip(&mut self, mut steps: usize) { 
     for _ in self { 
      steps -= 1; 
      if steps <= 0 { 
       break; 
      } 
     } 
    } 
} 

fn main() { 
    let s = "abc123def"; 
    let mut chars = s.chars(); 
    chars.skip(2); 
    println!("{:?}", chars.collect::<String>()); 
} 

오류 :

error: use of moved value: `chars` [--explain E0382] 
    --> <anon>:20:22 
19 |>  chars.skip(2); 
    |>  ----- value moved here 
20 |>  println!("{:?}", chars.collect::<String>()); 
    |>      ^^^^^ value used here after move 
<anon>:20:22: 20:27: note: in this expansion of format_args! 
<anon>:20:22: 20:27: note: in this expansion of print! (defined in <std macros>) 
<anon>:20:22: 20:27: note: in this expansion of println! (defined in <std macros>) 
note: move occurs because `chars` has type `std::str::Chars<'_>`, which does not implement the `Copy` trait 

error: aborting due to previous error 
playpen: application terminated with error code 101 
+0

을이 작동하지 않습니다 어떻게 해결하는 이유는 대답은 설명하지만, 솔직히 그것은 바로 다음 stdlib의를 사용하는 것이 좋습니다 매우 가능성이 높습니다 API가 약간 다르더라도 '건너 뛰기'합니다 (변경 메소드 대신 반복자 어댑터입니다). 나는 동의 반복자를 돌연변이 일부 실험 후 – delnan

+0

@delnan! 오류가 있습니다 –

답변

4

Can a value be moved by taking a mutable reference?

호 참조는 항목 참조-에 이동하지 마십시오. 그것은 하나의 큰 참고 점입니다.

그러나, Iterator::skip는 움직임이다 반복자의 소유권을 가지고 간다 :

fn skip(self, n: usize) -> Skip<Self> 

오류를 해결하기를, 당신은 ... 변경 가능한 참조를 취할 수 있습니다!

chars.by_ref().skip(2); 

그러나, 사용하지 않고 반복자 어댑터를 호출 있습니다 그것은 아무것도하지 않습니다 :

warning: unused result which must be used: iterator adaptors are lazy and do nothing unless consumed

여기 실제 문제는 당신이 호출되지 않습니다이다 skip 당신은 당신이 생각한다. 메서드 이름을 skip2으로 변경하면 의도 한대로 작동합니다. 방법 조회 전에별로 가변 레퍼런스 (&mut self) 전에 의해 참조 (&self)에 의해 값 (self) 수신기를 접수 방법을 선호하기 때문에

이있다.

그것은 아마도 특히 반복자를 들어, 표준 라이브러리와 동일한 방법으로 이름을 선택하는 나쁜 생각하지만, 경고가 범위에서 여러 적용 방법이있다라고 인쇄되지 않습니다 매우 놀라운 일이다.

당신은 그래도 전화를 할 구현 지정 Universal Function Call Syntax (UFCS)을 사용할 수

pub trait Skip: Iterator { 
    fn skip(&mut self, steps: usize) { 
     for _ in self.take(steps) {} 
    } 
} 

impl<I> Skip for I where I: Iterator {} 

fn main() { 
    let s = "abc123def"; 
    let mut chars = s.chars(); 
    Skip::skip(&mut chars, 2); 
    println!("{:?}", chars.collect::<String>()); 
} 
+1

경우 '건너 뛰기 :: skip' 걸릴로 변경된'그것이 MUT 기준에라고 직접 또는 경우 I' (예를 들어,'(MUT 문자) .skip (2)'). 그것은 다른 법률의 이유는 좀 더 구체적이고 따라서 선호하는, 그래서 Iterator'의 방법은 autoref를 필요로하지 않는다 '는 것이다. 'rustc'의 보푸라기는 예쁜 벌거 벗은 뼈이지만, clippy는 보푸라기가 있습니다. – delnan

+0

내가 방법을 선택합니다 할 순서 ('다음 self''및 다음 self''& MUT self')이 있는지 궁금 @delnan하고 "여러 적용 방법"오류는 같은 클래스에 여러 방법이있을 때 발생한다? – Shepmaster

+0

만든 GitHub의 문제 : https://github.com/rust-lang/rust/issues/34041 –

관련 문제