နားလည်ထားရမယ့် အချက်
Closure ဆိုတာ anonymous function တစ်မျိုးဖြစ်ပြီး named function နှင့် ကွာတဲ့ အချက်ကတော့ closure က define လုပ်ထားတဲ့ scope ထဲက variable တွေကို "capture" လုပ်နိုင်တာပါ—`|word| word.len() > min_length` လို closure ထဲက `min_length` ကို enclosing scope ကနေ ကိုးကားနိုင်ပါတယ်။ Closure က variable ကို capture လုပ်တဲ့နည်းလမ်း သုံးမျိုးရှိပါတယ်—borrow (`&T`, default, read-only access), mutable borrow (`&mut T`), move (ownership take, `move` keyword ဖြင့် explicit)—ဒီ choice ကို Lesson 6/7 ရဲ့ ownership rule အတိုင်းပဲ compiler က automatically ဆုံးဖြတ်ပေးပါတယ်။ Iterator ဆိုတာ collection ကို element တစ်ခုချင်းစီ traverse ဖြစ်စေတဲ့ lazy sequence ဖြစ်ပြီး `map` (transform), `filter` (select), `collect` (final collection အဖြစ် materialize) လို adapter method တွေက chain ဖြစ်ပြီး lazy evaluation—`collect()` ကို ခေါ်မှသာ actual computation စတင်ပါတယ်—ဒါကြောင့် `iter.filter(...).map(...).collect()` chain ရေးရင် intermediate collection တွေ (filter result ကို ခွဲသိမ်းစရာ) ဆောက်စရာ မလိုတော့ပါ။ ဒီ iterator chain ကတော့ Java Stream API/JavaScript array method chain နှင့် ရုပ်ပိုင်းဆိုင်ရာ ဆင်တူပေမယ့် Rust မှာ monomorphization ကြောင့် (Lesson 13) hand-written `for` loop နှင့် performance အတိအကျ တူညီတဲ့ zero-cost abstraction ဖြစ်ပါတယ်—readability ကို readable style နဲ့ ရေးလို့ရပေမယ့် runtime cost ဘာမှ ထပ်ပေးစရာ မလိုပါဘူး—Rust community က ဒီ characteristic ကို "you don't pay for what you don't use" လို့ ခေါ်ကြပါတယ်။
လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
Content analyzer ရဲ့ "minimum word count ကျော်တဲ့ lesson များကိုသာ ရှာ" logic ကို closure ဖြင့် `lessons.iter().filter(|l| l.word_count > min_words).collect()` လို ရေးမယ်—closure က `min_words` ကို enclosing scope ကနေ borrow လုပ်ကာ ခေါ်ပါတယ်။ Lesson title အားလုံးကို uppercase ပြောင်းချင်ရင် `lessons.iter().map(|l| l.title.to_uppercase()).collect::<Vec<String>>()` ဖြင့် chain ရေးမယ်—`for` loop ထက် readable ဖြစ်ပေမယ့် monomorphization ကြောင့် performance ဘာမှ ကျစရာ မလိုပါ။ Word count total ကို ရှာချင်ရင် `lessons.iter().map(|l| l.word_count).sum::<u32>()` ဖြင့် readable one-liner ရေးမယ်—intermediate `Vec` ကို build ချစရာ မလိုဘဲ lazy evaluation ကြောင့် `sum()` ခေါ်တဲ့အချိန်မှာပဲ traverse တစ်ကြိမ်တည်း ဖြစ်ပါတယ်။
အတူတူ စမ်းရေးကြည့်မယ်
struct Lesson { title: String, word_count: u32 }
fn main() {
let lessons = vec![
Lesson { title: String::from("Ownership"), word_count: 620 },
Lesson { title: String::from("Closures"), word_count: 340 },
Lesson { title: String::from("Traits"), word_count: 700 },
];
let min_words = 500;
let long_titles: Vec<String> = lessons
.iter()
.filter(|l| l.word_count > min_words)
.map(|l| l.title.to_uppercase())
.collect();
println!("{long_titles:?}");
let total: u32 = lessons.iter().map(|l| l.word_count).sum();
println!("total words: {total}");
}`["OWNERSHIP", "TRAITS"]` နှင့် "total words: 1660" ကို print ထုတ်နိုင်မည်။၅ မိနစ် စမ်းကြည့်
Integer `Vec<u32>` တစ်ခု ဖန်တီးပါ—`filter` ဖြင့် even number များသာ ရွေးပြီး `map` ဖြင့် နှစ်ဆတိုးကာ `collect()` ဖြင့် `Vec<u32>` အသစ်တစ်ခု ဖန်တီးပါ—closure တစ်ခုစီထဲမှာ variable တစ်ခု (threshold) ကို capture ထည့်သုံးကြည့်ပါ။
သတိလေးတစ်ချက်
Closure ကို `move` keyword ဖြင့် unnecessary သုံးပြီး outer scope ရဲ့ variable ကို ownership take သွားစေခြင်း—ဒီ variable ကို closure ပြီးနောက် outer scope ထဲက ဆက်သုံးမရတော့ဘဲ compile error ရနိုင်ပါတယ်—borrow (default) လုံလောက်ရင် `move` မလိုအပ်ပါ။
Iterator chain ကို `collect()` မခေါ်ဘဲ (lazy ဖြစ်လို့) actual computation ပြီးသွားပြီလို့ ထင်ခြင်း—`iter.filter(...)` တစ်ခုတည်းကို statement အဖြစ်ရေးရုံနှင့် ဘာမှ execute မဖြစ်သေးပါ—compiler က "unused iterator" warning ပေးလေ့ရှိပါတယ်။
The Rust Programming Language — Processing a Series of Items with Iterators — Rust