“This is the sixth day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”


Generics and traits are two of the most important concepts in the Rust type system.

Generics are not a concept specific to Rust and are supported in many strongly typed programming languages. Generics allow developers to write code that specifies the type only when it is used.

The trait in Rust, which borroops from Haskell’s Typeclass. It is also the cornerstone of Rust’s zero-cost abstraction.

  1. Traits are Rust’s only interface abstraction
  2. It can be distributed statically or invoked dynamically
  3. Can be used as a “tag” that has some specific behavior for a tag type

The bottom line: Traits are abstractions of type behavior.

The generic

In the type signature of a generic type, the letter T is usually used to represent a generic type. That is, the Option < T > enumeration type works for any type.

In this case, there is no need to define an Option enumeration for each type, such as Option < u32 > or Option < String >. The Option < T > type provided by the standard library is already automatically introduced into every Rust package by using STD :: Prelude ::v1::*, so Some(T)/None can be used directly to represent an Option < T > type, Instead of writing Option::Some(T) or Option::None.

Trait

pub trait Fly {
    fn fly(&self) - >bool;
}
struct Duck;
struct Pig;
// impl block
impl Fly for Duck {
    fn fly(&self) - >bool {
        return true; }}impl Fly for Pig {
    fn fly(&self) - >bool {
        return false; }}// use Triat
fn fly_static<T: Fly>(s: T) -> bool {
    s.fly()
}
fn fly_dyn(s: &Fly) -> bool {
    s.fly()
}

fn main() {
	let pig = Pig;
	assert_eq!(fly_static::<Pig>(pig), false);
	let duck = Duck;
	assert_eq!(fly_static::<Duck>(duck), true);
	assert_eq!(fly_dyn(&Pig), false);
	assert_eq!(fly_dyn(&Duck), true);
}
Copy the code

We need to focus on two points:

fly_static()

Fly_static

(s: T) Where: T: the grammatical form of Fly uses the Fly Trait to limit the behavior of the generic T → represents the type that realizes the Fly Trait or has the Fly behavior.

This restriction is called Trait bound in Rust.

Through Trait bound, you limit the type range of fy_static generic function parameters. If a type is passed that does not meet this qualification, the compiler recognizes it and reports an error.

fy_static::<Pig>

Assert! Assertion that determines whether the fy_static:: < Pig > (Pig) call will return false. A syntax like :: < Pig > is used to specify a specific type for a generic function, in this case the fly method implemented by Pig is called.

This invocation is called static distribution in Rust.

The Rust compiler generates specialized code for fy_static:: < Pig > (Pig) and FY_static :: < Duck > (Duck) calls of two concrete types. That is, for the compiler, this abstraction does not exist, because at compile time the generic type has already been expanded into concrete type code.