Rust
Marking done
Mark a task done by index.
Marking
To mark a task as done, we must find it by id and change its field. iter_mut().find(..) gives a &mut reference to the first matching element inside an Option:
fn tamamla(&mut self, id: u32) -> bool {
match self.gorevler.iter_mut().find(|g| g.id == id) {
Some(g) => {
g.bitti = true;
true
}
None => false,
}
}
Returning false for an unknown id lets the caller show the user a message.
Shortening with if let
The same method can be written more briefly with if let:
fn tamamla(&mut self, id: u32) -> bool {
if let Some(g) = self.gorevler.iter_mut().find(|g| g.id == id) {
g.bitti = true;
return true;
}
false
}
A similar method is used for deleting: self.gorevler.retain(|g| g.id != id); keeps the ones that don't match.
Exercise Complete a task
Write the methods ekle, tamamla and listele for Liste. Add two tasks ("Süt al", "Kod yaz"); first print the results of tamamla(2) and tamamla(9) separated by a space, then show the list.
Show example solution
struct Gorev {
id: u32,
metin: String,
bitti: bool,
}
struct Liste {
gorevler: Vec<Gorev>,
sonraki_id: u32,
}
impl Liste {
fn ekle(&mut self, metin: &str) -> u32 {
self.sonraki_id += 1;
self.gorevler.push(Gorev {
id: self.sonraki_id,
metin: metin.to_string(),
bitti: false,
});
self.sonraki_id
}
fn tamamla(&mut self, id: u32) -> bool {
match self.gorevler.iter_mut().find(|g| g.id == id) {
Some(g) => {
g.bitti = true;
true
}
None => false,
}
}
fn listele(&self) {
for g in &self.gorevler {
let isaret = if g.bitti { "x" } else { " " };
println!("[{}] {}: {}", isaret, g.id, g.metin);
}
}
}
fn main() {
let mut liste = Liste {
gorevler: Vec::new(),
sonraki_id: 0,
};
liste.ekle("Süt al");
liste.ekle("Kod yaz");
let a = liste.tamamla(2);
let b = liste.tamamla(9);
println!("{} {}", a, b);
liste.listele();
}
Test yourself
-
Why didn't we use <code>self.gorevler[id as usize]</code>?
- Indexing doesn't exist in Rust
- It would be slower
- u32 can't be indexed
- Ids aren't the same as indexes (they start at 1 and shift after deletions), and a wrong id panics
Show answer
Ids aren't the same as indexes (they start at 1 and shift after deletions), and a wrong id panics — Searching by id is both correct and safe; if nothing is found, None is returned and there's no panic.
-
Mutable search
match self.gorevler.____().find(|g| g.id == id) {
Some(g) => { g.bitti = true; true }
None => false,
}
Show answer
match self.gorevler.iter_mut().find(|g| g.id == id) {
Some(g) => { g.bitti = true; true }
None => false,
}
-
Method and result
- iter_mut().find(..)
- Option<&mut Gorev>
- retain(|g| g.id != 2)
- 2 is removed
- tamamla(9)
- false
- gorevler[9]
- Panic
Next lesson: Reading commands