Generics
Rust Generics
Parameters of kind "type"
Most commonly single capital letter (can be camel-case)
Can parameterize a datatype, function or impl (
examples/top.rs
)Turbofish supplies explicit type parameters
t.update::<u32>(&0);
Type Inference
As with lifetimes, usually don't have to write generics out: compiler can match things up
Sometimes gets lost, though. Also, will not make choices
// Fails to compile, for a lot of reasons. let s = [1, 2, 3].iter().cloned().sum();
Materialization
Generics are implemented by erasure: a new implementation of the datatype or function is created for each place the the thing is used at a type
This defines an infinity of potential instantations:
fn id<T>(x: T) -> T { x }
Inlining will happen and avoid some of these functions
Still, this can cause an explosion of implementations
fn tuple<T, U, V> (x: T, y: U, z: V) -> (T, U, V)
can have a lot of implementations floating around
Phantom Types
Sometimes want to have the compiler track the type of a thing just to avoid confusion
struct Hash { h: u128, }
This is the hash of some specific type: even if the
h
values match, if the types they were derived from do not that should failAsk the compiler to track this
use std::marker::PhantomData; struct Hash<T> { h: u128, p: PhantomData<T>, }
Now you can get typed hashes
impl<T> Hash<T> { fn hash(val: T) -> Hash<T> { let h = unsafe { hasher(&T) }; Hash { h, p: PhantomData } } }
examples/phantom.rs
for the details