Rust
Const trait bound
Use trait bounds with const generics.
Types and traits with const parameters
Types with const parameters can implement traits and be used in trait bounds. Since the size is part of the type, a size mismatch is a compile error; no runtime check is needed:
struct Vektor<const N: usize>([f64; N]);
impl<const N: usize> Vektor<N> {
fn nokta(&self, o: &Self) -> f64 {
self.0.iter().zip(o.0.iter()).map(|(a, b)| a * b).sum()
}
}
let a = Vektor([1.0, 2.0, 3.0]);
let b = Vektor([4.0, 5.0, 6.0]);
println!("{}", a.nokta(&b)); // 32
// a.nokta(&Vektor([1.0, 2.0])); // error: Vektor<3> expected
Implementing traits
A single trait implementation can be written for all sizes:
impl<const N: usize> Default for Vektor<N> {
fn default() -> Self {
Vektor([0.0; N])
}
}
impl<const N: usize> std::ops::Add for Vektor<N> {
type Output = Self;
fn add(self, o: Self) -> Self {
let mut t = [0.0; N];
for i in 0..N { t[i] = self.0[i] + o.0[i]; }
Vektor(t)
}
}
Exercise Dot product
Write the Vektor<const N: usize> type above and the nokta method. Print the dot product of Vektor([1.0, 2.0, 3.0]) and Vektor([4.0, 5.0, 6.0]).
Show example solution
struct Vektor<const N: usize>([f64; N]);
impl<const N: usize> Vektor<N> {
fn nokta(&self, o: &Self) -> f64 {
self.0.iter().zip(o.0.iter()).map(|(a, b)| a * b).sum()
}
}
fn main() {
let a = Vektor([1.0, 2.0, 3.0]);
let b = Vektor([4.0, 5.0, 6.0]);
println!("{}", a.nokta(&b));
}
Test yourself
-
How would the same error be caught with a <code>Vec<f64></code>-based vector?
- Only at runtime, by comparing lengths
- At compile time
- It couldn't be
- By type checking
Show answer
Only at runtime, by comparing lengths — Const generics move an invariant into the type system; the error is shown before the program runs.
-
For all sizes
impl____ Default for Vektor<N> {
fn default() -> Self {
Vektor([0.0; N])
}
}
Show answer
impl<const N: usize> Default for Vektor<N> {
fn default() -> Self {
Vektor([0.0; N])
}
}
-
Expression and result
- Vektor([1.0, 2.0, 3.0]).nokta(&b)
- 32
- Vektor<3> · Vektor<2>
- Compile error
- Vektor::<4>::default()
- [0.0; 4]
- Vektor<2> + Vektor<2>
- Vektor<2>
Next lesson: Min_const_generics