首页 rust

语言基础篇

类型系统

泛型

函数名使用snake case规范风格

struct Rectangle1<T> {
    width: T,
    height: T,
}

struct Rectangle2<T, U> {
    width: T,
    height: U,
}

impl<T> Rectangle1<T> {
    fn width(&self) -> &T {
        &self.width
    }

    fn height(&self) -> &T {
        &self.height
    }
}

impl Rectangle1<i32> {
    fn area(&self) -> i32 {
        self.width * self.height
    }
}

impl<T, U> Rectangle2<T, U> {
    fn width(&self) -> &T {
        &self.width
    }

    fn height(&self) -> &U {
        &self.height
    }
}

fn main() {
    let rect1 = Rectangle1 {width: 8, height: 2};
    println!("rect1.width: {}, rect1.height: {}", rect1.width(), rect1.height());
    println!("rect1.area: {}", rect1.area());
    
    let rect2 = Rectangle2 { width: 8, height: 2.2};
    println!("rect2.width: {}, rect2.height: {}", rect2.width(), rect2.height());
}

Rectangle1泛型是T,所以不能前后不一致,例如前面是i32,后面就不能是f64,但是Rectngle2就可以前后类型不一致

泛型与枚举

fn option_add(x: Option<i32>, y: Option<i32>) -> Option<i32> {
    return if x.is_none() && y.is_none() { None }
        else if x.is_none() { y }
        else if y.is_none() { x }
        else { Some(x.unwrap() + y.unwrap()) };
}

fn option_print(opt: Option<i32>) {
    match opt {
        Some(result) => println!("Option: {}", result),
        _ => println!("Option is None!"),
    }
}

fn main() {
    let result1 = option_add(Some(3), Some(5));
    let result2 = option_add(Some(3), None);
    let result3 = option_add(None, None);

    option_print(result1);
    option_print(result2);
    option_print(result3);
}

// enum Option<T> {
//     Some<T>,
//     None,
// }

这里在写option<T>的泛型使用方法

泛型与函数

函数的参数与返回值都可以是泛型类型

泛型也可以写方法,具体函数见泛型

trait系统

在几何图形中,都会求周长与面积,而其周长与面积的方法就可以写进一个trait中

trait Geometry {
    fn area(&self) -> f32;
    fn perimeter(&self) -> f32;
}

这个可以在impl中实现

trait Geometry {
    fn area(&self) -> f32;
    fn perimeter(&self) -> f32;
}
struct Rectangle {
    width: f32,
    height: f32,
}
impl Geometry for Rectangle {
    fn area(&self) -> f32 {
        self.width * self.height
    }
    fn perimeter(&self) -> f32 {
        (self.width + self.height) * 2.0
    }
}
struct Circle {
    radius: f32,
}
impl Geometry for Circle {
    fn area(&self) -> f32 {
        3.14 * self.radius * self.radius
    }
    fn perimeter(&self) -> f32 {
        3.14 * 2.0 * self.radius
    }
}
fn main() {
    let rect = Rectangle {width: 8.0, height: 2.0};
    println!("rect.area: {}, rect.perimeter: {}",
        rect.area(), rect.perimeter())
}

就像接口一样,但是可以作为参数,比其他语言的接口更方便

trait Geometry {
    fn area(&self) -> f32;
    fn perimeter(&self) -> f32;
}
fn print(geometry: impl Geometry) {
    println!("area: {}, perimeter: {}",
        geometry.area(), geometry.perimeter())
}
struct Rectangle {
    width: f32,
    height: f32,
}
impl Geometry for Rectangle {
    fn area(&self) -> f32 {
        self.width * self.height
    }
    fn perimeter(&self) -> f32 {
        (self.width + self.height) * 2.0
    }
}
fn main() {
    let rect = Rectangle {width: 8.0, height: 2.0};
    print(rect);
}

将原本的接口再次进行了包装

fn可以在impl中写并运用trait做接口

也可用多个trait做接口

也可将返回值设为trait

fn return_geometry() -> impl Geometry {
    Rectangle {
        width: 12.5,
        height: 5.5,
    }
}

NaN != NaN

enum BookFormat {
    Paperback,
    Hardback,
    Ebook,
}

struct Book {
    isbn: i32,
    format: BookFormat,
}

impl PartialEq for Book {
    fn eq(&self, other: &Self) -> bool {
        self.isbn == other.isbn
    }
}

这里重写了eq方法,只要两个Book的isbn相同,就是同一本书

类型转换

let x : u16 = 7;
let y = x as u32;

let x = std::u32::MAX
let y = x as u16;

可以进行放缩


豆瓣链接:https://book.douban.com/subject/35447165/




文章评论

目录