Rust
Beginner
1 min read
Const Generics and Phantom Types
Example
use std::marker::PhantomData;
// --- Const generics ---
fn sum_array<const N: usize>(arr: [i32; N]) -> i32 {
arr.iter().sum()
}
#[derive(Debug)]
struct Matrix<const ROWS: usize, const COLS: usize> {
data: [[f64; COLS]; ROWS],
}
impl<const ROWS: usize, const COLS: usize> Matrix<ROWS, COLS> {
fn new() -> Self {
Matrix { data: [[0.0; COLS]; ROWS] }
}
fn shape(&self) -> (usize, usize) { (ROWS, COLS) }
}
// --- Phantom types ---
struct User;
struct Post;
#[derive(Debug, Clone, Copy)]
struct Id<T> {
value: u64,
_phantom: PhantomData<T>,
}
impl<T> Id<T> {
fn new(value: u64) -> Self {
Id { value, _phantom: PhantomData }
}
}
fn get_user_name(_id: Id<User>) -> &'static str { "Alice" }
// fn get_user_name(_id: Id<Post>) — would be a type error at call site
fn main() {
println!("sum [1,2,3] = {}", sum_array([1, 2, 3]));
println!("sum [10,20] = {}", sum_array([10, 20]));
let m: Matrix<3, 4> = Matrix::new();
println!("matrix shape: {:?}", m.shape());
let user_id: Id<User> = Id::new(1);
let post_id: Id<Post> = Id::new(1);
println!("user_id = {:?}", user_id);
println!("post_id = {:?}", post_id);
println!("user name = {}", get_user_name(user_id));
// get_user_name(post_id); // compile error: expected Id<User>, got Id<Post>
}