Rust
Generic structure
Make the book model generic.
Generic structure
Let's write a Raf (shelf) to hold the books. Making the shelf generic lets the same code be used later for magazines or films:
pub struct Raf<T> {
ogeler: Vec<T>,
}
impl<T> Raf<T> {
pub fn new() -> Self { Self { ogeler: Vec::new() } }
pub fn ekle(&mut self, x: T) { self.ogeler.push(x); }
pub fn len(&self) -> usize { self.ogeler.len() }
}
Since the Vec stays private, changing the shelf's internals later (e.g. to a BTreeMap) doesn't affect users.
Implementing Default
For types offering an argument-less new, implementing Default is also a convention; then Raf::default() and ..Default::default() work:
impl<T> Default for Raf<T> {
fn default() -> Self {
Self::new()
}
}
let mut sayilar: Raf<u32> = Raf::default();
sayilar.ekle(7);
Thanks to type inference, Raf::new() is usually used without writing the type: the first ekle call determines T.
Exercise Two shelves
Inside mod kitaplik, together with the previous Kitap, write a generic Raf<T> (new, ekle, len). Add two books to a book shelf and three numbers to a u32 shelf; print the lengths of both shelves separated by a space.
Show example solution
mod kitaplik {
pub struct Kitap {
ad: String,
yazar: String,
yil: u16,
}
impl Kitap {
pub fn new(ad: &str, yazar: &str, yil: u16) -> Self {
Self {
ad: ad.to_string(),
yazar: yazar.to_string(),
yil,
}
}
pub fn ad(&self) -> &str {
&self.ad
}
pub fn yil(&self) -> u16 {
self.yil
}
}
pub struct Raf<T> {
ogeler: Vec<T>,
}
impl<T> Raf<T> {
pub fn new() -> Self {
Self { ogeler: Vec::new() }
}
pub fn ekle(&mut self, x: T) {
self.ogeler.push(x);
}
pub fn len(&self) -> usize {
self.ogeler.len()
}
}
}
use kitaplik::{Kitap, Raf};
fn main() {
let mut kitaplar = Raf::new();
kitaplar.ekle(Kitap::new("Tutunamayanlar", "Oğuz Atay", 1972));
kitaplar.ekle(Kitap::new("Kürk Mantolu Madonna", "Sabahattin Ali", 1943));
let mut sayilar: Raf<u32> = Raf::new();
for n in [1, 2, 3] {
sayilar.ekle(n);
}
println!("{} {}", kitaplar.len(), sayilar.len());
}
Test yourself
-
What does Clippy suggest for a type with <code>pub fn len</code>?
- Nothing
- Adding pub fn is_empty too
- Removing len
- Renaming len to size
Show answer
Adding pub fn is_empty too — The len_without_is_empty lint: is_empty is an expected API on collection-like types.
-
Generic impl
impl____ Raf<T> {
pub fn ekle(&mut self, x: T) {
self.ogeler.push(x);
}
}
Show answer
impl<T> Raf<T> {
pub fn ekle(&mut self, x: T) {
self.ogeler.push(x);
}
}
-
Expression and T
- Raf<Kitap>
- Book shelf
- Raf<u32>
- Number shelf
- Raf::new() + ekle("a")
- Raf<&str>
- Raf::<f64>::default()
- Empty f64 shelf
Next lesson: Searching with traits