泛型与trait

2021-08-28  本文已影响0人  简书网abc

1. 在函数中使用泛型

// 参与比较需要实现std::cmp::PartialOrd 这个特性
fn main() {
    fn largest<T: std::cmp::PartialOrd>(list: &[T]) -> &T {
        let mut largest: &T = &list[0];
        for item in list.iter() {
            if item > largest {
                largest = item;
            }
        }
        return largest;
    }

    let number_list = vec![34, 50, 25, 100, 342];
    let result = largest(&number_list);
    println!("The largest number is {}", result);

    let char_list = vec!['y', 'm', 'a', 'q'];
    let result = largest(&char_list);
    println!("The largest char is {}", result);
}

2. 在结构体中定义泛型

#[derive(Debug)]
// 在结构体中定义泛型
struct Point<T, U> {
    x: T,
    y: U,
}
fn main() {
    let both_integer = Point{x: 4, y: 5};
    println!("both_integer : {:?}", both_integer);
}

3. 在结构体方法中定义泛型

struct Point<T, U> {
    x: T,
    y: U,
}
// impl 块本身的泛型并没有阻碍其内部方法具有泛型的能力:
impl <T, U> Point<T, U> {
    fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> {
        Point {
            x: self.x,
            y: other.y,
        }
    }
}

fn main() {
    let p1 = Point { x: 5, y: 10.4 };
    let p2 = Point { x: "Hello", y: 'c'};
    let p3 = p1.mixup(p2);
    println!("p3.x = {}, p3.y = {}", p3.x, p3.y);
}
//结果: p3.x = 5, p3.y = c

4. 默认特性

trait Descriptive {
    fn describe(&self) -> String {  //在这里定义默认特性
        String::from("[object]")
    }
}

struct Person {
    name: String,
    age: u8,
}
//在这里实现这个特性
impl Descriptive for Person {
    //覆盖默认实现
    fn describe(&self) -> String {
        format!("my name is {}, age is {}", self.name, self.age)
    }
}

fn main() {
    let cali = Person{
        name: String::from("Ming"),
        age: 123,
    };
    println!("{}", cali.describe());
}

//结果: my name is Ming, age is 123

5, trait作为参数

// 功能的定义者 接口
pub trait Summary {
    fn summarize_author(&self) -> String;
    fn summarize(&self) -> String {
        format!("(Read from Summary  {} ... )", self.summarize_author())
    }
}

// 功能的实现者 结构体
struct Person {
    name: String,
}
impl Summary for Person {
    fn summarize_author(&self) -> String {
        format!("(Read from person {} ... )", self.name)
    }
}

// 功能的 调用者
fn notify<T: Summary>(item: T) {
    println!("{}", item.summarize())
}

fn main() {
    let obj = Person{
        name: "MingMing".to_string(),
    };
    // 使用者
    notify(obj);    //在此处被正式使用
}

//结果: (Read from Summary  (Read from person MingMing ... ) ... )

6. 使用 trait bound 有条件地实现方法

// 根据 trait bound 在泛型上有条件的实现方法
use std::fmt::Display;

// 类型 Pair<T> 总是实现了 new 方法,
// 不过只有那些为 T 类型实现了 PartialOrd trait (允许比较) 和 Display trait (启用打印)的 Pair<T>
// 才会实现 cmp_display 方法
struct Pair<T> {
    x: T,
    y: T,
}
impl<T> Pair<T> {
    //结果体关联函数的定义
    fn new(x: T, y: T) -> Self {    // Self 和 self 啥区别???
        Self {
            x,
            y
        }
    }
}
impl<T: Display + PartialOrd> Pair<T> {
    // 使用 trait bound 有条件地实现方法
    fn comp_display(&self) {
        if self.x >= self.y {
            println!("max num is {}", self.x);
        } else {
            println!("max num is {}", self.y);
        }
    }
}

fn main() {
    let pp = Pair::new(234, 88);
    pp.comp_display();
}

//结果: max num is 234

7. 对任何实现了特定trait的类型有条件的实现trait

//对任何实现了特定trait的类型有条件的实现trait
// 有点类似于类继承
trait GetName {
    fn get_name(&self) -> &String;
}
trait PrintName {
    fn print_name(&self);
}
//为实现了 GetName 特性的类型 实现 PrintName 特性(有条件)
impl <T: GetName> PrintName for T {
    fn print_name(&self) {
        println!("name is {}", self.get_name())
    }
}

struct Student {
    name: String,
}
// 这里实现了 GetName 就相当于实现了 PrintName
// 这种用法有点类似于类继承
impl GetName for Student {
    fn get_name(&self) -> &String {
        &self.name
    }
}

fn main() {
    let s = Student{
        name: String::from("xiao_ming"),
    };
    s.print_name()
}

// 结果: name is xiao_ming

8. 特性作为返回值

trait GetAge {
    fn get_age(&self) -> u32;
}
pub struct Student {
    pub name: String,
    pub age: u32,
}
impl GetAge for Student {
    fn get_age(&self) -> u32 {
        self.age
    }
}

fn produce_item_with_age() -> impl GetAge {
    Student {
        name: String::from("xiao_ming"),
        age: 15,
    }
}
fn main() {
    let s = produce_item_with_age();
    println!("age is = {:?}", s.get_age());
}

//结果: age is = 15
上一篇下一篇

猜你喜欢

热点阅读