Generics
Generics in Rust enable you to write flexible, reusable code that works with different data types while ensuring type safety.
We use generics to create definitions for items like function signatures or structs, which we can then use with many different concrete data types.
Represented by angle brackets (
<>
) and often denoted byT
,U
, or other descriptive names.Rust generates optimized code for each concrete type used with a generic at compile time, avoiding runtime overhead.
References:
generics1.rs
// `Vec<T>` is generic over the type `T`. In most cases, the compiler is able to
// infer `T`, for example after pushing a value with a concrete type to the vector.
// But in this exercise, the compiler needs some help through a type annotation.
fn main() {
// Fix the compiler error by annotating the type of the vector
// `Vec<T>`. Choose `T` as some integer type that can be created from
// `u8` and `i8`.
let mut numbers: Vec<i32> = Vec::new();
// Don't change the lines below.
let n1: u8 = 42;
numbers.push(n1.into());
let n2: i8 = -1;
numbers.push(n2.into());
println!("{numbers:?}");
}
In this exercise we just need to define the vector type.
We can use
i32
that satisfy bothu8
andi8
type that pushed in themain
function.
generics2.rs
// This powerful wrapper provides the ability to store a positive integer value.
// Rewrite it using a generic so that it supports wrapping ANY type.
struct Wrapper<T> {
value: T,
}
// Adapt the struct's implementation to be generic over the wrapped value.
impl<T> Wrapper<T> {
fn new(value: T) -> Self {
Wrapper { value }
}
}
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn store_u32_in_wrapper() {
assert_eq!(Wrapper::new(42).value, 42);
}
#[test]
fn store_str_in_wrapper() {
assert_eq!(Wrapper::new("Foo").value, "Foo");
}
}
In this exercise we tasked to build
Wrapper
that accepts generics.So we need to add
<T>
in struct definition and the implementation to make it generics.
Last updated