Learn Rust Coding · บทเรียน

ตัววนซ้ำแบบกำหนดเอง

นำ Iterator ไปใช้งาน

บทเรียน 4 จาก 413 ขั้นตอน

ตัววนซ้ำแบบกำหนดเอง เป็นบทเรียน Learn Rust Coding ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Learn Rust Coding และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน

สร้าง Iterator ของคุณเอง

คุณไม่ได้จำกัดอยู่แค่ Iterator ที่มีมาให้ในระบบ การนำคุณลักษณะ Iterator ไปใช้กับชนิดข้อมูลของคุณเอง จะทำให้ชนิดนั้นได้รับอะแดปเตอร์และตัวใช้ผลลัพธ์ทั้งหมดโดยไม่ต้องเขียนเพิ่ม

สิ่งที่คุณต้องจัดเตรียมมีเพียงชนิด Item และเมธอด next

โครงสร้าง Counter

เริ่มด้วยโครงสร้างที่เก็บสถานะของ Iterator ตัวนับอย่างง่ายต้องการเพียงค่าปัจจุบัน

struct Counter {
    count: u32,
}

fn main() {
    let c = Counter { count: 0 };
    println!("start at {}", c.count);
}

การนำ next ไปใช้

นำ Iterator ไปใช้กับโครงสร้าง กำหนด type Item แล้วเขียน next เพื่อเลื่อนสถานะและคืนค่า Some จนกว่าจะถึงเงื่อนไขหยุด จากนั้นจึงคืนค่า None

struct Counter { count: u32 }

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.count < 5 {
            self.count += 1;
            Some(self.count)
        } else {
            None
        }
    }
}

fn main() {
    let mut c = Counter { count: 0 };
    println!("{:?}", c.next());
    println!("{:?}", c.next());
}

การใช้ในลูป for

เมื่อมี next แล้ว ชนิดข้อมูลของคุณก็จะใช้งานในลูป for ได้เหมือน Iterator มาตรฐานทุกประการ

struct Counter { count: u32 }

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.count < 5 { self.count += 1; Some(self.count) } else { None }
    }
}

fn main() {
    for n in (Counter { count: 0 }) {
        print!("{} ", n);
    }
    println!();
}

อะแดปเตอร์และตัวใช้ผลลัพธ์ที่มีให้โดยอัตโนมัติ

เพราะคุณนำเมธอดหนึ่งรายการไปใช้ เครื่องมือของ Iterator ทั้งหมดจึงพร้อมใช้งาน ในที่นี้ เราหาผลรวมกำลังสองของค่าจากตัวนับที่จับคู่กัน

struct Counter { count: u32 }

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.count < 5 { self.count += 1; Some(self.count) } else { None }
    }
}

fn main() {
    let total: u32 = Counter { count: 0 }.map(|x| x * 2).sum();
    println!("{}", total);
}

เมธอดตัวสร้าง

เพิ่มฟังก์ชัน new เพื่อไม่ให้ผู้ใช้ต้องเข้าถึงฟิลด์ภายในโดยตรง วิธีนี้สะอาดกว่าและช่วยให้คุณเก็บฟิลด์ไว้เป็นส่วนตัวได้

struct Counter { count: u32 }

impl Counter {
    fn new() -> Counter { Counter { count: 0 } }
}

impl Iterator for Counter {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.count < 3 { self.count += 1; Some(self.count) } else { None }
    }
}

fn main() {
    let v: Vec<u32> = Counter::new().collect();
    println!("{:?}", v);
}

Iterator แบบ Fibonacci

Iterator สามารถเก็บสถานะที่ซับซ้อนขึ้นได้ ตัวสร้าง Fibonacci จะเก็บค่าสองค่าล่าสุดและอัปเดตค่าเหล่านั้นเมื่อเรียก next แต่ละครั้ง

struct Fib { a: u64, b: u64 }

impl Iterator for Fib {
    type Item = u64;
    fn next(&mut self) -> Option<u64> {
        let current = self.a;
        self.a = self.b;
        self.b = current + self.b;
        Some(current)
    }
}

fn main() {
    let fib = Fib { a: 0, b: 1 };
    let seq: Vec<u64> = fib.take(8).collect();
    println!("{:?}", seq);
}

Iterator แบบไม่สิ้นสุดก็ใช้ได้

Iterator ของ Fibonacci จะไม่คืนค่า None — เพราะเป็นลำดับที่ไม่สิ้นสุด วิธีนี้ปลอดภัยเนื่องจากการทำงานแบบขี้เกียจทำให้สร้างค่าเมื่อมีการร้องขอเท่านั้น ใช้ take เพื่อจำกัดขอบเขต

struct Fib { a: u64, b: u64 }

impl Iterator for Fib {
    type Item = u64;
    fn next(&mut self) -> Option<u64> {
        let c = self.a;
        self.a = self.b;
        self.b = c + self.b;
        Some(c)
    }
}

fn main() {
    let big = Fib { a: 0, b: 1 }.nth(20);
    println!("{:?}", big);
}

การวนผ่านชนิดข้อมูลห่อหุ้ม

บ่อยครั้งคุณจะนำ Iterator ไปใช้กับโครงสร้างช่วยเหลือที่ยืมข้อมูลของคุณ ในที่นี้ ตัวเลื่อนจะให้ผลลัพธ์เป็นตัวเลขเว้นทีละหนึ่งจากช่วงข้อมูลที่เก็บอยู่ภายใน

struct EvenUpTo { current: u32, max: u32 }

impl Iterator for EvenUpTo {
    type Item = u32;
    fn next(&mut self) -> Option<u32> {
        if self.current > self.max { return None; }
        let value = self.current;
        self.current += 2;
        Some(value)
    }
}

fn main() {
    let evens: Vec<u32> = (EvenUpTo { current: 0, max: 10 }).collect();
    println!("{:?}", evens);
}

เหตุใดจึงควรสร้าง Iterator แบบกำหนดเอง

Iterator แบบกำหนดเองช่วยให้คุณส่งค่าทีละค่าได้โดยไม่ต้องจองหน่วยความจำสำหรับคอลเลกชันทั้งหมด ใช้จำลองลำดับข้อมูลแบบไม่สิ้นสุดหรือลำดับที่คำนวณขึ้น และมอบอินเทอร์เฟซที่คุ้นเคยและนำไปประกอบต่อได้แก่ผู้เรียกใช้

เมธอด next ขนาดเล็กเพียงรายการเดียวจะเปิดทางให้ใช้ระบบนิเวศทั้งหมดได้

เคล็ดลับการออกแบบ

เก็บสถานะให้มีขนาดเล็ก คืนค่า None เพียงครั้งเดียวเมื่อสิ้นสุด (หรือไม่คืนเลยสำหรับ Iterator แบบไม่สิ้นสุด) และหลีกเลี่ยงงานหนักภายใน next เพื่อให้การทำงานแบบขี้เกียจยังมีต้นทุนต่ำ

ตรวจสอบความเข้าใจอย่างรวดเร็ว

การนำคุณลักษณะ Iterator ไปใช้

สรุปทบทวน

คุณได้สร้าง Iterator แบบกำหนดเอง:

  • เก็บสถานะไว้ในโครงสร้าง แล้วเขียน impl Iterator
  • กำหนด type Item และเขียน next
  • ได้รับอะแดปเตอร์และตัวใช้ผลลัพธ์ทั้งหมดทันทีโดยไม่ต้องเขียนเพิ่ม
  • Iterator อาจมีขอบเขตสิ้นสุดหรือไม่สิ้นสุดก็ได้ ใช้ take เพื่อจำกัด Iterator แบบไม่สิ้นสุด
เริ่มต้นได้ฟรี

เรียนรู้ Rust ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
39
บทเรียน
144

คำถามที่พบบ่อย

บทเรียน “ตัววนซ้ำแบบกำหนดเอง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ตัววนซ้ำแบบกำหนดเอง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Learn Rust Coding ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ตัววนซ้ำแบบกำหนดเอง”

นำ Iterator ไปใช้งาน คุณปฏิบัติ Learn Rust Coding ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Learn Rust Coding หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Learn Rust Coding บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “ตัววนซ้ำแบบกำหนดเอง” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Learn Rust Coding นี้ได้ไหม

ได้ บทเรียน Learn Rust Coding ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. คุณลักษณะ Iterator
  2. map, filter, collect
  3. ตัวปรับและตัวรับผล
  4. ตัววนซ้ำแบบกำหนดเอง
← กลับไปที่ Learn Rust Coding