Traits and Generics
Generics and traits for reusable, typed abstractions. Results appear in the same fence: same-line // comments when short, multiline // blocks below the sample when not.
Busque em todas as páginas da documentação
Generics and traits for reusable, typed abstractions. Results appear in the same fence: same-line // comments when short, multiline // blocks below the sample when not.
Type parameters in angle brackets.
fn first<T>(xs: &[T]) -> Option<&T> { xs.first() }
first(&[10, 20]).copied() // Some(10)Require behavior with : Trait.
fn stringify<T: std::fmt::Display>(v: T) -> String {
format!("{v}")
}
stringify(42) // "42"Opaque return types without naming the concrete type.
fn nums() -> impl Iterator<Item = i32> {
[1, 2, 3].into_iter()
}
nums().sum::<i32>() // 6Readable bounds for complex signatures.
fn max_of<T>(a: T, b: T) -> T
where
T: PartialOrd,
{
if a >= b { a } else { b }
}
max_of(3, 5) // 5Trait methods with default bodies allowed.
trait Greet {
fn greet(&self) -> String;
}
impl Greet for &str {
fn greet(&self) -> String { format!("hi {self}") }
}
"Ada".greet() // "hi Ada"Dynamic dispatch with dyn Trait.
fn len(s: &dyn AsRef<str>) -> usize { s.as_ref().len() }
len(&"ab") // 2Conversions with From / Into.
let s: String = String::from("x");
let t: String = "y".into();
s.len() + t.len() // 2Generic over borrowed forms.
fn chars<S: AsRef<str>>(s: S) -> usize {
s.as_ref().chars().count()
}
chars(String::from("hi")) // 2Provide defaults for types.
#[derive(Default)]
struct C { n: i32 }
C::default().n // 0Explicit deep-ish copies.
#[derive(Clone)]
struct P { x: i32 }
P { x: 1 }.clone().x // 1Adapters from the Iterator trait.
let v: Vec<_> = [1, 2, 3].iter().map(|x| x * 2).collect();
v // [2, 4, 6]Combine bounds with +.
fn show<T: std::fmt::Debug + Clone>(v: T) -> String {
format!("{:?}", v.clone())
}
show(1) // "1"Traits can declare associated types.
trait Bag {
type Item;
fn first(&self) -> Option<&Self::Item>;
}
impl Bag for Vec<i32> {
type Item = i32;
fn first(&self) -> Option<&i32> { self.get(0) }
}
vec![9, 8].first() // Some(9)Mark generic ownership without storing T.
use std::marker::PhantomData;
struct Id<T> { n: u64, _t: PhantomData<T> }
Id::<u8> { n: 1, _t: PhantomData }.n // 1Generic over compile-time values.
fn first_n<const N: usize>(a: [i32; N]) -> i32 { a[0] }
first_n([7, 8, 9]) // 7Stack versions: Rust 1.97.0 · edition 2024 · Tokio 1.x · serde 1.0
Revisado por Chris St. John·Última atualização: 18 de jul. de 2026