fn identity<T>(t: T) -> T { t }
Has no trait bounds, and is clearly generic. You typically can't do very much with completely free type variables, but Rust has syntactic support for them.However, note that there does exist a very important generic function in the stdlib that doesn't use traits at all: `std::mem::drop`. Here's the source, which is very, very interesting: https://github.com/rust-lang/rust/blob/4ed2edaafe82fb8d44e81... . And no, I'm not being facetious when I call it interesting; figuring out what `std::mem::drop`'s purpose is from its amusing implementation is a test that you understand what ownership means in Rust. :)
Traits do a lot of things in Rust that have nothing to do with generics. :) Implementing a trait is how one gives a type a destructor. Implementing various traits (the ones in std::ops) allows one to do operator overloading for user-defined types. Defining a trait allows one to give methods to types that are defined in other compilation units, including the standard library, e.g.:
trait Foo {
fn foo(self);
}
impl Foo for i32 {
fn foo(self) {
println!("Hello, traits!");
}
}
fn main() {
42.foo(); // Hello, traits!
}https://doc.rust-lang.org/std/io/trait.Read.html https://doc.rust-lang.org/std/io/trait.Write.html