学习Rust中泛型和trait

起因

学习Rust中的泛型和trait.

泛型, 和c#泛型差不多,这里简单学习一下

struct Point<T> {
    x: T,
    y: T,
}

impl<T> Point<T> {
    fn get_x(&self) -> &T {
        &self.x
    }

    fn get_y(&self) -> &T {
        &self.y
    }
}

fn main() {
    let point_i32 = Point { x: 10, y: 10 };
    let point_f32 = Point { x: 1.0, y: 30.1 };
    println!("point_i32 x:{}", point_i32.get_x());
    println!("point_f32 x:{}", point_f32.get_y());
}

创建一个trait,trait相当于其他语言c#/Java中接口

///# 结构体
///# 定义结构体,通过#[derive(Debug)]注解,才能让println!打印结构体内容
#[derive(Debug)]
struct People {
    id: u32,
    //id
    name: &'static str,
    //姓名 字符串
    sex: &'static str, //性别
}

/// 通过trait 关键字,定义trait
trait PrintInfo {
    /// 方法/函数,没有具体实现
    fn info(&self) -> String;
}

/// 通过impl和for关键字,给People实现PrintInfo这个trait
impl PrintInfo for People {
    fn info(&self) -> String {
        String::from("hello trait")
    }
}

trait DefaultImpl {
    /// trait中的方法也可以默认实现
    fn default_impl(&self) {
        println!("default impl")
    }
}

impl DefaultImpl for People {}

fn main() {
    let p = People {
        id: 1,
        name: "tom",
        sex: "man",
    };

    println!("info:{}", p.info());

    p.default_impl();

}

rust中的trait 使用和默认实现

trait中可以继承

/// 通过trait 关键字,定义trait
trait PrintInfo {
    /// 方法/函数,没有具体实现
    fn info(&self) -> String;
}

/// InheritTrait这个trait,继承PrintInfo
trait InheritTrait: PrintInfo {
    fn out_info(&self) {
        println!("inherit function");
    }
}

impl InheritTrait for People {}

impl PrintInfo for People {
    fn info(&self) -> String {
        String::from("hello rust trait")
    }
}

fn main() {
    let p = People {
        id: 1,
        name: "tom",
        sex: "man",
    };

    println!("info:{}", p.info());

    p.out_info();
}

Rust中trait继承另外一个trait

Add这个trait,实现其他语言的操作符功能

#[derive(Debug)]
struct MyPoint {
    x: i32,
    y: i32,
}

impl Add for MyPoint {
    type Output = MyPoint;
    fn add(self, mypoint: MyPoint) -> Self {
        MyPoint {
            x: self.x + mypoint.x,
            y: self.y + mypoint.y,
        }
    }
}

fn main() {

    let a = MyPoint { x: 10, y: 30 };
    let b = MyPoint { x: 20, y: 20 };

    //println!("{:?}", a.add(b));
    println!("{:?}", a + b);  //a+b本质上是a.add(b)
}

通过trait可以实现其他语言中的操作符重载

通过tarit给类型实现扩展方法

trait MethodExtesion {
    fn printinfo(&self) {
        println!("i32 printinfo:{}", 10);
    }
}

impl MethodExtesion for i32 {}

fn main() {
    let x: i32 = 10;
    x.printinfo();
}

通过trait,给i32类型实现扩展方法

标签trait

标签trait没有具体实现,只是一个声明,具体有编译器处理.
#[stable(feature = "rust1", since = "1.0.0")]
#[lang = "sized"]
#[rustc_on_unimplemented(
    on(parent_trait="std::path::Path", label="borrow the `Path` instead"),
    message="the size for values of type `{Self}` cannot be known at compilation time",
    label="doesn't have a size known at compile-time",
    note="to learn more, visit <https://doc.rust-lang.org/book/\
          ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>",
)]
#[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
pub trait Sized {
    // Empty.
}
源码在libcore/marker.rs中.
Rust中内置重要的trait,如Sized,Unsize
Sized: 用于编译器在编译期间确定大小
UnSize: 用于标识动态大小
Copy: 用于按位复制
Send:用于跨线程安全通信
Sync:用于线程间安全共享引用
Unpin:用于固定后可以移动的类型
StructuralPartialEq和StructuralEq是用于匹配模式.

秋风 2020-03-22