美文网首页
泛型与trait

泛型与trait

作者: 简书网abc | 来源:发表于2021-08-28 15:42 被阅读0次

    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
    

    相关文章

      网友评论

          本文标题:泛型与trait

          本文链接:https://www.haomeiwen.com/subject/hymbiltx.html