La généricité et des types composés
Ces exercices portent sur les types génériques, les traits, les tuples et les
attributs #[derive]. Faites-les dans l'ordre.
Maximum générique
Écrire une fonction qui renvoie le plus grand de deux éléments, quel que soit leur type - du moment qu'on peut les comparer.
- Objectif : paramètre générique
<T>, contrainteT: PartialOrd. - Signature suggérée :
fn maximum<T: PartialOrd>(a: T, b: T) -> T. - Cas de test :
maximum(3, 8)->8,maximum(2.5, 1.0)->2.5,maximum("abc", "abd")->"abd".
Paire générique
Définir struct Paire<T> { premier: T, second: T } et une fonction qui renvoie
une nouvelle paire avec les deux champs échangés.
- Objectif :
structgénérique, fonction (ou méthode) générique. - Signature suggérée :
fn echanger<T>(p: Paire<T>) -> Paire<T>. - Cas de test :
echanger(Paire { premier: 1, second: 2 })->Paire { premier: 2, second: 1 }.
Trait Aire
Définir trait Aire { fn aire(&self) -> f64; } et l'implémenter pour
struct Cercle { rayon: f64 } et struct Carre { cote: f64 }.
- Objectif : définition d'un trait,
impl Trait for Type. - Signature suggérée :
trait Aire { fn aire(&self) -> f64; }. - Cas de test :
Carre { cote: 3.0 }.aire()->9.0,Cercle { rayon: 2.0 }.aire()-> environ12.566.
Trait avec méthode par défaut
Définir trait Decrire avec une méthode nom(&self) -> String (obligatoire) et
une méthode decrire(&self) -> String par défaut qui renvoie
format!("Ceci est {}", self.nom()). Implémenter le trait pour un premier type
en ne fournissant que nom, puis pour un second type en redéfinissant aussi
decrire.
- Objectif : méthode par défaut d'un trait, redéfinition.
- Signature suggérée :
trait Decrire { fn nom(&self) -> String; fn decrire(&self) -> String { /* défaut */ } }. - Cas de test : un
Chatqui ne définit quenom(renvoyant"un chat") ->decrire()="Ceci est un chat"; un type qui redéfinitdecrire-> sa propre chaîne.
Point<T> et somme des coordonnées
Définir struct Point<T> { x: T, y: T } et une méthode somme(&self) -> T qui
renvoie x + y, disponible seulement lorsque T supporte l'addition.
- Objectif :
impl<T: ...>avec contrainte (std::ops::Add<Output = T> + Copy). - Signature suggérée :
impl<T: Add<Output = T> + Copy> Point<T> { fn somme(&self) -> T }. - Cas de test :
Point { x: 3, y: 4 }.somme()->7,Point { x: 1.5, y: 2.5 }.somme()->4.0.