特质实现及其对象

学习内容

  • 理解衔接类型关键词trait的实现

篇目

程序结构图与衔接类型关键词trait

image

实现基于默认方法的关键词trait代码

  通过下面的代码,可以学习到这些知识:

  • 使用关键词trait,定义了特质TraitCanal的默认实例化函数init()
  • 使用关键词implfor,基于结构类型StructType,为特质TraitCanal实现了方法new()、get_data()set_data()`;
  • 借助于特质TraitCanal的默认实例化函数init(),实现该结构类型的实例化方式;
mod trait_exerci {
    #[derive(Debug)]
    pub struct StructType {
        pub data: u32,
    }

    pub trait TraitCanal {
        fn new(data: u32) -> StructType;
        fn init() -> StructType { StructType{data:0} }
        fn get_data(&self) -> u32;
        fn set_data(&mut self, data: &u32);
    }

    impl TraitCanal for StructType {
        fn new(data: u32) -> StructType {
            StructType { data: data }
        }

        fn get_data(&self) -> u32 {
            self.data
        }

        fn set_data(&mut self, data: &u32) {
            self.data = *data;
        }
    }
}

use self::trait_exerci::TraitCanal;

// cargo run --example trait_with_default_method
fn main() {
    let mut instance = trait_exerci::StructType::new(10);
    instance.set_data(&11);
    println!("new {:?}", instance);

    let mut instance = trait_exerci::StructType::init();
    instance.set_data(&12);
    println!("init {:?}", instance);
}

特质对象解释

  特质本身不能定义特质对象,而是通过类型的对象,进行强制转换得到的特质对象。特质对象可以访问类型的公共数据和公共特质的行为。

  Rust语言把面向对象编程的思想更加深化了。把类的数据与行为分散化定义,而把类的实例集成化使用。不仅如此,而且Rust语言在代码里完全把这种过程都隐藏起来了。

image

题外话

什么是可衍生特质

  Rust语言标准库或者第三方提供了一些非常有用的特质,称之为可衍生特质(Derivable Trait)。通过注释#[derive(特质名称)],编译器能够为这些特质提供实现。比如,要求类型实现是可打印的,可以使用特质std::fmt::Debug。具体说,使用可衍生特质#[derive(Debug)],所有类型都可以自动创建地实现std::fmt::Debug。

  下面的代码里第一行就是注释可衍生特质Debug,为类型Person实现了特质Debug,这些后面的宏println!()就可以使用了这个特质。

  注意,使用注释#[derive(特质名称)],必须紧挨着类型定义之上。

#[derive(Debug)]
struct Person {
  name: String,
  age: u32,
}

impl Person {
    fn init() -> Person {
        Person {
            name: String::new(),
            age: 0,
        }
    }
}

fn main() {
    let person = Person::init();
    println!("{:?}", person);
}

参考资料