最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

Rust 知识积累(6)

来源:博客园
  • impl Trait


    (资料图片仅供参考)

    • 使用(与泛型类似)

      // 入参 举例// 类似与 fn prints_it>(input: T){}fn prints_it(input: impl Into + std::fmt::Display){    // 直接输出入参    println!("{}", input);}fn main(){    // c_str    prints_it("hi");    // String    prints_it(String::from("Hi"));}
  • 闭包

    在我理解。。。类似于反射的声明,然后在这个声明中调用该类的方法,期间该方法与其他代码相互独立

    // 使用impl声明一个闭包 FnMut(i32) 得到的就是numberfn returns_closure(input: &st)->impl FnMut(i32)->i32{    match input{        // 判断input是否为double,如果是则传入的number加2        "double" => |mut number|{            number += 2;            number        }    }}fn main(){// 调用    let mut doubles = returns_closure("double");    doubles(10);}
  • Arc 原子引用计数器

    线程或同时运算时保持原子性的类型

    // 引用Arc和Mutex包use std::sync::{Arc, Mutex};fn main(){    // 声明原子计数    let my_number = Arc::new(Mutex::new(0));    // 声明一个数组    let mut handle_vec = Vec![];     // 从0开始循环    for _ in 0..2{        let my_number = Arc::Clone(&my_number);        let handle = std::thread::spawn(move || {            for _ in 0..10{                *my_number.lock().unwrap() += 1;            }        });        handle_vec.push(handle);    }    handle_vec.into_iter().for_each(|handle| handle.join().unwrap());    // 结果为20    println!("{:?}", my_number); }
  • Channels

    通道,类似于socket连接时,一个是发送端,一个是接收端一样

    // 生产者和消费者需要绑定在一起pub fn channel()->(Sender, Recever)// 声明use std::sync::mpsc::{channel, Sender, Receiver};let (s, r):(Sender, Receiver) = channel();// 简写use std::sync::mpsc::channel;let (sender, receiver) = channel();sender.send(5);receiver.recv();//线程中使用use std::sync::mpsc::channel;fn main() {    let (sender, receiver) = channel();    let sender_clone = sender.clone();    // 使用线程向管道中发送一条信息    std::thread::spawn(move|| {         sender.send("Send a &str this time").unwrap();    });// 通过克隆的参数向管道中发送一条信息    std::thread::spawn(move|| {         sender_clone.send("And here is another &str").unwrap();    });    // 打印接收内容内容    println!("{:?}", receiver.recv().unwrap());    // 如何同时打印两个信息    // 使用 let mut handle_vec = vec![];保存线程返回变量    // for _ in handle_vec{} // 遍历中使用receiver.recv().unwarp();可同时显示两个}
属性

以"# []"或"# ![]"声明的 例如:

"# [derive(Debug)]" 影响下一行代码

"# ![derive(Debug)]" 将影响整个空间

  • 写了没有使用的代码,仍然会编译

    // #[allow(dead_code)] 和 #[allow(unused_variables)]// struct 只是声明,没有使用#![allow(dead_code)]#![allow(unused_variables)]// 声明了很多不同的structstruct Struct1 {} struct Struct2 {}struct Struct3 {}struct Struct4 {}struct Struct5 {}fn main() {    // 声明了四个变量,编译器不会进行任何操作    let char1 = "ん";     let char2 = ";";    let some_str = "I"m just a regular &str";    let some_vec = vec!["I", "am", "just", "a", "vec"];}
  • 创建结构和枚举派生

    // 该声明以后,HoldsAString都可以使用#[derive(Debug)]struct HoldsAString {    the_string: String,}fn main() {    let my_string = HoldsAString {        the_string: "Here I am!".to_string(),    };    // 结果为:Here I am!    println!("{:?}", my_string);}
  • 配置

    "#[cfg()]"的意思是配置 ,例如"# [cfg(test)] " // 告诉编译器不要运行他们,除非是在测试"# [cfg(target_os = "windows")] " // windows环境下运行"# ![no_std]" // 不要引入std的标准库

Box

  • 使用Box时,可以把一个类型放在堆上而不是栈上

  • 可以将它作为智能指针使用

//1let my_box = Box::new(1); // This is Box let an_integer = *my_box; // this is i32//2struct List{ item: Option>,}impl List{    fn new() -> List{        List{            item: Som(Box::new(List{item: None})),        }    }}fn main(){    let mut my_list = List::new();}
  • Box包裹trait

    use std::error::Error;use std::fmt;#[derive(Debug)]struct ErrorOne;// Error带有Debug类型impl Error for ErrorOne {}// ErrorOne中重写了fmt方法impl fmt::Display for ErrorOne {    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {        // 向自身写入You got the first error!字符串        write!(f, "You got the first error!")     }}// 与ErrorOne类似#[derive(Debug)] struct ErrorTwo;impl Error for ErrorTwo {}impl fmt::Display for ErrorTwo {    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {        write!(f, "You got the second error!")    }}// 声明一个调用方法fn returns_errors(input: u8) -> Result> {     match input {        // 注意 将ErrorOne和ErrorTwo都进行了装盒        0 => Err(Box::new(ErrorOne)),         1 => Err(Box::new(ErrorTwo)),        // 当成功的时候返回该字符串        _ => Ok("Looks fine to me".to_string()),     }}fn main() {    // 声明了一个数组,并存储了三个数值    let vec_of_u8s = vec![0_u8, 1, 80];     for number in vec_of_u8s {        // 循环数组,根据不同的数值返回不同的结果        match returns_errors(number) {            Ok(input) => println!("{}", input),            Err(message) => println!("{}", message),        }    }}

默认值

  • Default::default()

    // 主要使用let default_i8 : i8 = Default::default();       // 0let default_str : String = Default::default();  // ""let default_bool : bool = Default::default();   // false// struct默认值#[derive(Debug)]struct Character {    name: String,    age: u8,    height: u32,    weight: u32,    lifestate: LifeState,}#[derive(Debug)]enum LifeState {    Alive,    Dead,    NeverAlive,    Uncertain,}impl Character {    fn new(name: String, age: u8, height: u32, weight: u32, alive: bool) -> Self {        Self {            name,            age,            height,            weight,            lifestate: if alive {                LifeState::Alive            } else {                LifeState::Dead            },        }    }}impl Default for Character {    fn default() -> Self {        Self {            name: "Billy".to_string(),            age: 15,            height: 170,            weight: 70,            lifestate: LifeState::Alive,        }    }}fn main() {    let character_1 = Character::default();    println!(        "The character {:?} is {:?} years old.",        character_1.name, character_1.age    );}

建造者模式

// 注意 mut self而不是&mut self// 改变自身的height,并返回自身fn height(mut self, height: u32) -> Self {       self.height = height;    self}// 调用Character::default().height(180)

Deref和DerefMut

  • 通过实现Deref,可以将智能指针视作常规引用来进行处理。

    use std::ops::Deref;impl Deref for MyBox {  type Target = T; // 类型标注后边会有介绍,可先忽略  fn deref(&self) -> &T { // 返回成员的引用    &self.0  }}assert_eq!(5, *y); // 事实上*y会被编译成 *(y.deref())
  • 使用new实例化,等返回self时只会返回Deref中的设置信息

    use std::ops::Deref;#[derie(Debug)]struct HoldsANumber(u8);impl Deref for HoldsANumber{    type Target = u8;    fn deref(&self)->&Self::Target{        &self.0    }}let my_num = HoldsANUmber(20);println!("{:?}", *my_num + 20)// 标准库实例use std::ops::Deref;struct DerefExample{    value:T}impl Deref for DerefExample{    type Target = T;    fn deref(&self) -> &Self::Target{        &self.alue    }}fn main(){    let x = DerefExample{ value:"a"};    assert_eq!("a", *x);}
  • checked_sub() 安全的减法,整数可直接使用,如果失败返回None,不会崩溃

  • DerefMut 与Deref使用基本一致,唯一的不同是有了Mut,意味着可修改,使用前必须引用和实现Deref

    use std::ops::{Deref, DerefMut};struct HoldsANumber(u8);impl HoldsANumber {    fn prints_the_number_times_two(&self) {        println!("{}", self.0 * 2);    }}// 使用DerefMut之前必须先声明Derefimpl Deref for HoldsANumber {    type Target = u8;    fn deref(&self) -> &Self::Target {        &self.0    }}// 这个因为使用了Deref,因此不需要输入:Target = u8;impl DerefMut for HoldsANumber {     fn deref_mut(&mut self) -> &mut Self::Target {        &mut self.0    }}fn main() {    let mut my_number = HoldsANumber(20);    *my_number = 30;    println!("{:?}", my_number.checked_sub(100));    my_number.prints_the_number_times_two();}

Create和模块

// 声明一个modmod print_things{    use std::fmt::Display;    //必须加pub    pub fn prints_one(input: T){        println!("{}", input);    }}fn main(){    use create::print_thines::prints_one;    prints_one(6);   }

关键词: