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
반환 된 반복자가 완전히 혼란 스럽지만 배열의 경우이 반복자는 동일합니까?iter
into_iter
이 두 가지 방법의 사용 사례 / API는 무엇입니까?
첫 번째 질문은 "무엇입니까 into_iter
?"
into_iter
IntoIterator
특성 에서 온다 :
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:
IntoIterator
is not implemented for[T; N]
, only for&[T; N]
and&mut [T; N]
- 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 referenceinto_iter()
iterates over the items, moving them into the new scopeiter_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
'programing tip' 카테고리의 다른 글
Django에서 정적 STATIC_URL과 STATIC_ROOT의 차이점 (0) | 2020.08.06 |
---|---|
AngularJS 지시문에서 '대체'속성이 더 이상 사용되지 않는 이유는 무엇입니까? (0) | 2020.08.06 |
Angular 2 템플릿에서 let- *는 무엇입니까? (0) | 2020.08.06 |
문자열 및 레이블의 지역화 및 세계화에 대한 모범 사례 (0) | 2020.08.06 |
C에서이 "[0… 255] ="구문은 무엇입니까? (0) | 2020.08.06 |