Exercice 1. Itération sur des Vec<..>
¶
Traduire en Rust la fonction Python suivante
def primes(N):
res = [2]
for i in range(3, N, 2):
for j in res:
if i % j == 0:
break
if j*j > i:
res.append(i)
break
return res
Exercice 2. Généricité bornée par des traits¶
Ajoutez les traits bornant les types génériques nécessaires dans le code ci-dessous.
fn sum<T: ..., U: ... >(container: U) -> T {
let mut res = Default::default();
for x in container {
res = res + x;
}
res
}
Exercice 3. Vecteurs de dimension 3¶
- Définissez le type
Vec3D
des vecteurs de dimension 3 (les coordonnées du vecteur seront représentées par des flotants 32 bits) - Ajoutez un constructeur
Vec3D::new(x, y, z)
. - Implémentez automatiquement les traits
Debug
,Clone
,Copy
, etPartialEq
pourVec3D
avec la macro#derive
. Pourquoi ne peut-on pas implémenter le traitEq
? - Implémentez le trait
Display
. Testez votre code avec le test ci-dessous (mettez ce code sous forme de test, et lancez-le depuis votre IDE ou aveccargo test
, voir TP précédent). Pourquoi le test compile-t-il alors que nulle part vous n'avez défini de méthode.to_string()
pourVec3D
?
let v = Vec3D::new(1.0, 2.0, 3.0);
assert_eq!(v.to_string(), "(1, 2, 3)".to_string());
- Implémentez le trait
Add
et testez.
let v1 = Vec3D::new(1.0, 2.0, 3.0);
let v2 = Vec3D::new(1.0, 1.0, 1.0);
assert_eq!((v1 + v2).to_string(), "(2, 3, 4)".to_string());
assert_eq!((v1 + 2.0).to_string(), "(3, 4, 5)".to_string());
assert_eq!((3.0 + v1).to_string(), "(4, 5, 6)".to_string());
- Implémentez le trait
Mul
et testez.
let v1 = Vec3D::new(1.0, 2.0, 3.0);
let v2 = Vec3D::new(1.0, -1.0, 2.0);
assert_eq!((v1 * v2), 5.0);
assert_eq!((v1 * 2.0).to_string(), "(2, 4, 6)".to_string());
assert_eq!((3.0 * v1).to_string(), "(3, 6, 9)".to_string());
- Pourquoi n'est-il pas possible d'étendre en plus le trait
Mul
pour noterv1 * v2
le produit vectoriel dev1 et v2
?
// ceci n'est pas possible, pourquoi?
let v1 = Vec3D::new(1, 2, 3);
let v2 = Vec3D::new(1, -1, 2);
let v3 : f32 = v1 * v2; // 5
let v4 : Vec3D = v1 * v2; // (7, 1, -3)
- Définissez un trait
Mult
(avec un t) le plus générique possible qui permette de surcharger une méthodemult
pourVec3D
, et implémentez-le pourVec3D
.
let v1 = Vec3D::new(1.0, 2.0, 3.0);
let v2 = Vec3D::new(1.0, -1.0, 2.0);
let v3: f32 = v1.mult(v2);
let v4: Vec3D = v1.mult(v2);
assert_eq!(v3, 5.0);
assert_eq!(v4.to_string(), "(7, 1, -3)".to_string());
- Définissez un trait
RMult
(avec un t) le plus générique possible qui permette de surcharger une méthodermult
pourVec3D
, et implémentez-le pourVec3D
. N'implémentez pasRMult
pourVec3D
, mais définissez plutôt un implémenteur qui génère automatiquement une implémentation deRMult
pour toute implémentation deMult
.
let v1 = Vec3D::new(1.0, 2.0, 3.0);
let v2 = Vec3D::new(1.0, -1.0, 2.0);
let v3: f32 = v2.rmult(v1);
let v4: Vec3D = v2.rmult(v1);
assert_eq!(v3, 5.0);
assert_eq!(v4.to_string(), "(7, 1, -3)".to_string());
- Faites de
Vec3D
un type sur lequel on peut itérer.
let v = Vec3D::new(1, 2, 3);
for x in &v { println!(x) };
for x in &mut v { *x += 1 };
for x in v { println!(x) };
1
2
3
2
3
4