Generics
Sometimes structures and functions are supposed to work for multiple datataypes:
use std::*;
struct I32Container {
item: i32
}
struct BoolContainer {
item: bool
}
// and so on...
fn main() {
let i32b = I32Container { item: 4 };
let bb = BoolContainer { item: false };
}
As an alternative to creating a variant for each possible type, we can replace the concrete item
type with a generic placeholder type T
:
use std::*;
struct Container<T> {
item: T
}
fn main() {
let i32b = Container::<i32> { item: 4 };
// `_` wildcard is inferred to be bool
let bb = Container::<_> { item: false };
// omitted type is inferred to be c_str
let strb = Container { item: "hello" };
}
We can also make methods generic to work on any T
:
use std::*;
struct Container<T> {
item: T
}
// "for any T we want a Container of T with the follwing methods"
impl<T> Container<T> {
fn wrap(item: T) -> Container<T> {
// wildcard inferred to be Container::<T>
_ { item: item }
}
// `self` name is arbitrary
fn unwrap(self: Container<T>) -> T {
self.item
}
}
fn main() {
let i32b = Box::<i32>::wrap(4);
let bb = Box::<_>::wrap(false);
// we still need wildcard to disambiguate
let strb = Box::<_>::wrap("hello");
let i = i32b.unwrap();
let b = bb.unwrap();
let s = strb.unwrap();
}
Note: Technically we already know one generic:
ptr<T>