跟着谷歌学习Rust:第十二课-标准库泛型

177 阅读2分钟

Comparisons

数据比较是Rust中的一个基础工具,通过该工具可以对变量或者对象做对比较。 Rust中的比较工具是通过trait实现的,实现之后重写对应的比较方法就可以实现对比。

PartialEq and Eq

struct Key {
    id: u32,
    metadata: Option<String>,
}
//实现PartialEq重写eq方法,通过id做比较
impl PartialEq for Key {
    fn eq(&self, other: &Self) -> bool {
        self.id == other.id
    }
}

PartialOrd and Ord

PartialOrd在Rust中用于排序,并且可以实现<<=>=, and >四种类型的排序。

use std::cmp::Ordering;
#[derive(Eq, PartialEq)]
struct Citation {
    author: String,
    year: u32,
}
impl PartialOrd for Citation {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        match self.author.partial_cmp(&other.author) {
            Some(Ordering::Equal) => self.year.partial_cmp(&other.year),
            author_ord => author_ord,
        }
    }
}


impl Ord for Citation {
    fn cmp(&self, other: &Self) -> Ordering {
        todo!()
    }
}

From and Into

类型转换是Rust中通过trait提供的类型转换工具,From和Into本质上都是做类型转换,主要的区别就是所属的trait不同。

fn main() {
    let s = String::from("hello");
    let addr = std::net::Ipv4Addr::from([127, 0, 0, 1]);
    let one = i16::from(true);
    let bigger = i32::from(123_i16);
    println!("{s}, {addr}, {one}, {bigger}");
}

fn main() {
    let s: String = "hello".into();
    let addr: std::net::Ipv4Addr = [127, 0, 0, 1].into();
    let one: i16 = true.into();
    let bigger: i32 = 123_i16.into();
    println!("{s}, {addr}, {one}, {bigger}");
}


//实现From的trait重写from
impl From for Citation {
    fn from(value: T) -> Self {
        todo!()
    }
}

Casting

Casting也是类型转换,具体是通过as实现的转换。和From、Into的区别是From和Into是trait需要实现重写对应方法才可以实现,但是as是一个关键字直接使用即可。

fn main() {
    let value: i64 = 1000;
    println!("as u16: {}", value as u16);
    println!("as i16: {}", value as i16);
    println!("as u8: {}", value as u8);
}

但是使用as会容易出错,如果类型的确不一致,强行使用as会出现异常。

Read and Write

IO读和IO写。

Rust中的IO操作也是通过缓冲区实现的,类似Java。

Read

use std::io::{BufRead, BufReader, Read, Result};

fn count_lines<R: Read>(reader: R) -> usize {
    let buf_reader = BufReader::new(reader);
    buf_reader.lines().count()
}

fn main() -> Result<()> {
    let slice: &[u8] = b"foo\nbar\nbaz\n";
    println!("lines in slice: {}", count_lines(slice));

    let file = std::fs::File::open(std::env::current_exe()?)?;
    println!("lines in file: {}", count_lines(file));
    Ok(())
}

Write

use std::io::{Result, Write};

fn log<W: Write>(writer: &mut W, msg: &str) -> Result<()> {
    writer.write_all(msg.as_bytes())?;
    writer.write_all("\n".as_bytes())
}

fn main() -> Result<()> {
    let mut buffer = Vec::new();
    log(&mut buffer, "Hello")?;
    log(&mut buffer, "World")?;
    println!("Logged: {:?}", buffer);
    Ok(())
}

Closures

闭包

引用

Google