programing tip

iter와 into_iter의 차이점은 무엇입니까?

itbloger 2020. 8. 6. 08:02
반응형

iter와 into_iter의 차이점은 무엇입니까?


이 코드 스 니펫이 있는 Rust by Example 튜토리얼을하고 있습니다.

// Vec example
let vec1 = vec![1, 2, 3];
let vec2 = vec![4, 5, 6];

// `iter()` for vecs yields `&i32`. Destructure to `i32`.
println!("2 in vec1: {}", vec1.iter()     .any(|&x| x == 2));
// `into_iter()` for vecs yields `i32`. No destructuring required.
println!("2 in vec2: {}", vec2.into_iter().any(| x| x == 2));

// Array example
let array1 = [1, 2, 3];
let array2 = [4, 5, 6];

// `iter()` for arrays yields `&i32`.
println!("2 in array1: {}", array1.iter()     .any(|&x| x == 2));
// `into_iter()` for arrays unusually yields `&i32`.
println!("2 in array2: {}", array2.into_iter().any(|&x| x == 2));

수율 참조에서 반환 된 반복자와 수율 값 에서 Vec반환 된 반복자가 완전히 혼란 스럽지만 배열의 경우이 반복자는 동일합니까?iterinto_iter

이 두 가지 방법의 사용 사례 / API는 무엇입니까?


첫 번째 질문은 "무엇입니까 into_iter?"

into_iterIntoIterator특성 에서 온다 :

pub trait IntoIterator 
where
    <Self::IntoIter as Iterator>::Item == Self::Item, 
{
    type Item;
    type IntoIter: Iterator;
    fn into_iter(self) -> Self::IntoIter;
}

특정 유형을 반복자로 변환하는 방법을 지정하려는 경우이 특성을 구현합니다. 특히 유형이 구현 IntoIterator하면 for루프 에서 사용할 수 있습니다 .

예를 들어 ... 3을 Vec구현합니다 IntoIterator!

impl<T> IntoIterator for Vec<T>
impl<'a, T> IntoIterator for &'a Vec<T>
impl<'a, T> IntoIterator for &'a mut Vec<T>

각 변형은 약간 다릅니다.

이것은 소비 Vec하고 반복자는 값을 산출 합니다 ( T직접).

impl<T> IntoIterator for Vec<T> {
    type Item = T;
    type IntoIter = IntoIter<T>;

    fn into_iter(mut self) -> IntoIter<T> { /* ... */ }
}

다른 두 개는 참조로 벡터를 취하고 ( 두 경우 모두 참조 into_iter(self)이므로 서명에 속지 마십시오 self) 반복자는 내부 요소에 대한 참조를 생성 Vec합니다.

이것은 불변의 참조를 산출합니다 .

impl<'a, T> IntoIterator for &'a Vec<T> {
    type Item = &'a T;
    type IntoIter = slice::Iter<'a, T>;

    fn into_iter(self) -> slice::Iter<'a, T> { /* ... */ }
}

이것은 가변 참조를 생성 하지만 :

impl<'a, T> IntoIterator for &'a mut Vec<T> {
    type Item = &'a mut T;
    type IntoIter = slice::IterMut<'a, T>;

    fn into_iter(self) -> slice::IterMut<'a, T> { /* ... */ }
}

그래서:

차이점은 무엇이며 iter그리고 into_iter?

into_iter이 이터레이터가 값을 생성하는지, 불변의 참조 또는 변경 가능한 참조 가 컨텍스트에 따라 달라 지고 때로는 놀라운 지 여부에 관계없이 반복자를 얻는 일반적인 방법 입니다.

iter and iter_mut are ad-hoc methods. This works around the context-dependent bit and, by convention, let you obtain an iterator which will yield references.

The author of the Rust by Example post illustrates the surprise coming from the dependence on the context (i.e., the type) on which into_iter is called, and is also compounding the problem by using the fact that:

  1. IntoIterator is not implemented for [T; N], only for &[T; N] and &mut [T; N]
  2. When a method is not implemented for a value, it is automatically searched for references to that value instead

which is very surprising for into_iter since all types (except [T; N]) implement it for all 3 variations (value and references). It's not possible for the array to implement an iterator that yields values because it cannot "shrink" to give up its items.

As to why arrays implement IntoIterator (in such a surprising fashion): it's to make it possible to iterate over references to them in for loops.


.into_iter() is not implemented for a array itself, but only &[]. Compare:

impl<'a, T> IntoIterator for &'a [T]
    type Item = &'a T

with

impl<T> IntoIterator for Vec<T>
    type Item = T

Since IntoIterator is defined only on &[T], the slice itself cannot be dropped the same way as Vec when you use the values. (values cannot be moved out)

Now, why that's the case is a different issues, and I'd like to learn myself. Speculating: array is the data itself, slice is only a view into it. In practice you cannot move the array as a value into another function, just pass a view of it, so you cannot consume it there either.


I (a Rust newbie) came here from Google seeking a simple answer which wasn't provided by the other answers. Here's that simple answer:

  • iter() iterates over the items by reference
  • into_iter() iterates over the items, moving them into the new scope
  • iter_mut() iterates over the items, giving a mutable reference to each item

So for x in my_vec { ... } is essentially equivalent to my_vec.into_iter().for_each(|x| ... ) - both move the elements of my_vec into the ... scope.

If you just need to "look at" the data, use iter, if you need to edit/mutate it, use iter_mut, and if you need to give it a new owner, use into_iter.

This was helpful: http://hermanradtke.com/2015/06/22/effectively-using-iterators-in-rust.html

Making this a community wiki so that hopefully a Rust pro can edit this answer if I've made any mistakes.

참고URL : https://stackoverflow.com/questions/34733811/what-is-the-difference-between-iter-and-into-iter

반응형