Iterator vs IntoIterator สำหรับแบน

Oct 06 2020

ฉันกำลังเล่นกับตัววนซ้ำและฉันใช้Flattenเพื่อทำความเข้าใจวิธีการทำงานของตัววนซ้ำให้ดีขึ้น ตัวอย่างนี้:

assert_eq!(vec![1, 2].iter().flatten().count(), 2);

ไม่รวบรวมและให้ข้อผิดพลาด (เป็นข้อผิดพลาดหลักที่น่ากังวล):

error[E0277]: `&{integer}` is not an iterator
  --> src/lib.rs:59:38
   |
59 |         assert_eq!(vec![1, 2].iter().flatten().count(), 2);
   |                                      ^^^^^^^ `&{integer}` is not an iterator
   |
   = help: the trait `std::iter::Iterator` is not implemented for `&{integer}`
   = note: required because of the requirements on the impl of `std::iter::IntoIterator` for `&{integer}`

สิ่งที่สร้างความสับสนให้ฉันก็คือดูเหมือนว่าFlattenต้องซ้อนกันในการดำเนินการItem IntoIteratorฉันยืนยันสิ่งนี้ใน Rustdocs ที่พวกเขาประกาศ

pub struct Flatten<I> 
where
    I: Iterator,
    <I as Iterator>::Item: IntoIterator

เพียงแค่เตรียมเอกสารเท่านั้น IntoIterator ก็มีวิธีกำหนดวิธีการแปลงประเภทเป็นตัววนซ้ำ ทำไมถึงไม่สามารถผูกลักษณะได้<I as Iterator>::Item: Iterator? แน่นอนว่าถ้าไอเท็มที่ซ้อนกันใช้งานIteratorได้เราจะได้รับสิ่งเดียวกันFlattenเนื่องจากไอเท็มที่ซ้อนกันจะต้องเป็นผู้ทำซ้ำ มันนำความแตกต่าง / ประโยชน์อะไรมาใช้IntoIteratorแทน?

คำตอบ

1 twotwotwo Oct 06 2020 at 11:18

ต้องการIntoIteratorแทนที่จะIteratorให้คุณแบนคอลเลกชั่นคอลเลกชันนอกเหนือจากคอลเลกชันของตัววนซ้ำ

ตัวอย่างเช่นประเภทคอลเลกชันVecจะแตกต่างจากประเภทตัววนซ้ำดังนั้นหากflattenต้องการให้รายการเป็นIterators คุณจะไม่สามารถแบน a VecของVecs ได้

IntoIteratorหมายถึงประเภทที่สามารถแปลงเป็นตัววนซ้ำได้เช่นVecคอลเลกชันอื่น ๆ (หรือตัววนซ้ำ!) ตัวอย่างเช่นสิ่งนี้ได้ผล:

fn main() {
    let nested_vec: Vec<Vec<i32>> = vec![vec![1, 2], vec![3, 4]];
    let flat_vec: Vec<i32> = nested_vec.into_iter().flatten().collect();
    println!("{:?}", flat_vec);
}

คุณสามารถลองตัวอย่างนี้ในสนามเด็กเล่น การใช้into_iter()ด้านบนแทนiter()ทำให้แน่ใจว่าเราวนซ้ำบนi32s ไม่ใช่อ้างอิงถึงi32s (ขอบคุณ Cerberus ที่แนะนำinto_iter()แทนcopied())

(คุณสามารถดูประเภทอื่น ๆ อีกสองสามประเภทพร้อมIntoIteratorการใช้งานได้ในส่วน "การใช้งานในประเภทต่างประเทศ" ของเอกสาร)