Generic structure
- Rust course
- Intermediate
- Lesson 27/115
- 6 min
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.
Practice 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.
Starter code
fn main() {
// buraya yaz
}Sample 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());
}Expected output
2 3
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What does Clippy suggest for a type with <code>pub fn len</code>?
- Nothing
- Adding pub fn is_empty too Correct answer
- Removing len
- Renaming len to size
Explanation: The len_without_is_empty lint: is_empty is an expected API on collection-like types.
2 Generic impl
impl____ Raf<T> {
pub fn ekle(&mut self, x: T) {
self.ogeler.push(x);
}
}
impl<T> Raf<T> {
pub fn ekle(&mut self, x: T) {
self.ogeler.push(x);
}
}
Explanation: Methods valid for every T go in an impl<T> block.
3 Expression and T
| Term | Meaning |
|---|---|
Raf<Kitap> |
Book shelf |
Raf<u32> |
Number shelf |
Raf::new() + ekle("a") |
Raf<&str> |
Raf::<f64>::default() |
Empty f64 shelf |