Rust generic
Created By: chatGPT
Generics in Rust allow you to write flexible and reusable code by defining functions or types that can operate on different data types without sacrificing performance. They enable you to code in a way that's type-safe without needing to duplicate code for each specific type.
fn print_value<T: std::fmt::Display>(value: T) {
println!("Value: {}", value);
}
fn main() {
print_value(10); // integer
print_value(3.14); // float
print_value("Hello, world!"); // string
}
You can also use generics with structs and enums. By doing so, you can create a struct that can hold any type of data. This is particularly useful when you want to group types without losing type information.
struct Wrapper<T> {
value: T,
}
impl<T> Wrapper<T> {
fn new(value: T) -> Self {
Wrapper { value }
}
}
fn main() {
let int_wrapper = Wrapper::new(42);
let string_wrapper = Wrapper::new(String::from("Generics are great!"));
}
You can also define methods on generics by using
impl
blocks. This allows you to create methods that can work with any type specified when you create an instance of the generic struct.impl<T> Wrapper<T> {
fn get_value(&self) -> &T {
&self.value
}
}
fn main() {
let wrapped_value = Wrapper::new(100);
println!("Wrapped value: {}", wrapped_value.get_value());
}
Another important feature of generics is the ability to impose trait bounds, which specify that a type must implement certain traits. This allows you to use methods that belong to those traits within your generic functions or structs.
fn compare<T: PartialOrd>(a: T, b: T) -> T {
if a < b {
a
} else {
b
}
}
fn main() {
let smaller = compare(10, 20);
println!("Smaller value: {}", smaller);
}