forループ文
TL;DR
for文で回すには、以下のトレイトのどれかを実装する必要がある。
Iterator
IntoIterator
配列はforループで回せない
配列は、どちらも実装していないため、forループ文で直接回せない。
let arr = [1,2,3,4,5]; // NG for i in arr { dbg!(i); } /* error[E0277]: `[{integer}; 5]` is not an iterator --> /Users/yossan/testcodes/rust/garbage/vec_loop.rs:10:14 | 10 | for i in arr { | ^^^ borrow the array with `&` or call `.iter()` on it to iterate over it | = help: the trait `Iterator` is not implemented for `[{integer}; 5]` = note: arrays are not iterators, but slices like the following are: `&[1, 2, 3]` = note: required by `into_iter` */
- for文ないでは、スライス型への型強制がされない
- 配列上で、スライス型のメソッドを呼び出すと、スライス型に型強制する
配列の参照はforループで回せる
配列の参照型はIntoIterator<Item=&T>
を実装している。
impl<'a, T> IntoIterator for &'a [T] type Item = &'a T type IntoIter = Iter<'a, T>
for i in &arr { }
Vecはforループで回せる
Vecは、Iterator実装型ではないが、IntoIterator実装型であるため、for文で回すことが出来る。
impl<T, A: Allocator> IntoIterator for Vec<T, A> { type Item = T; type IntoIter = IntoIter<T, A>; fn into_iter(self) -> IntoIter<T, A> {
for文で使うと内部でinto_iterメソッドが呼び出されるため、所有権を失う
let vec = vec![1,2,3,4,5]; for i in vec { println!("{}", i); } dbg!(vec); /* 2 | let vec = vec![1,2,3,4,5]; | --- move occurs because `vec` has type `Vec<i32>`, which does not implement the `Copy` trait 3 | for i in vec { | --- | | | `vec` moved due to this implicit call to `.into_iter()` | help: consider borrowing to avoid moving into the for loop: `&vec` */
参照型の方も実装されているので、所有権を失いたくない場合は、参照型の方を使う。
impl<'a, T> IntoIterator for &'a Vec<T> type Item = &'a T type IntoIter = Iter<'a, T>
let vec = vec![1,2,3,4,5]; for i in &vec { dbg!(i); }