最新要闻

广告

手机

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

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

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

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

家电

世界速讯:Rust 知识积累(5)

来源:博客园

&str

字符串
  • 直接声明时,生命周期为整个程序,直接写进了二进制中,类型为&"static str",意为字符串字元有一个叫static的生命期
借用str
  • 作为String的引用来使用,无生命期,例如 fn print_str(my_str: &str){},调用为print_str(&String::format("string""));

生命期

  • 引用的生命期不能比这个对象长


    (资料图片)

    fn returns_str() -> &str{    return "I am" // ---错误,因为这个值声明是在方法内,引用出去后是null}// 改进fn returns_str() -> &‘static str{    return "I am" // ---正确,返回了字符串字面量,该值整个程序有效}

struct使用

  • 基础使用

    // 尝试写struct City<"a>和name: &"a str// 意思是 name可以存活到与City一样的生命期// a可以为任意值#[derive(Debug)]struct City<"a>{    name: &"a str,    date_f: u32,}let my_city = City{    name: &"China".to_string(),    date_f: 2022,}
  • 添加调用方法

    // 不仅仅struct要与name同一个生命期,impl也要一致struct Adventurer<"a>{    name: &"a str,    hit_points: u32,}impl Adventer<"_>{    fn take_damage(&mut self){        slef.hit_points -= 20;        println!("{} has {} hit", slef.name, self.hit_points);    }}fn main(){    let mut bi = Adventurer{        name:"Billy",        hit_points: 100,    }    bi.take_damage();}

内部可变性

  • 不用mut也可修改数据,例如Cell,RefCell,Mutex, RwLock

  • Cell

    // 给出的是值而不是引用use std::cell::Cell;struct PhoneModel{    on_sale: Cell,}fn main(){    let huawei_phone = PhoneModel{        on_sale: Cell::new(true),    };    huawei_phone.on_sale.set(false);}
  • RefCell

    // 引用单元格,引用// 小心使用,他是运行后编译use std::cell::RefCell;struce User{    active: RefCell,}fn main(){    let user_l = user{        active: RefCell::new(true),    };    println!("{}", user_l.active);    user_l.active.borrow();    user_l.active.borrow_mut(); //引出后就不能再borrow_mut()了    user_l.active.replace(false);}
  • Mutex

    线程安全,只让一个线程修改它(有lock())

    use std::sync::Mutex;let my_mutex = Mutex::new(5);// 加锁let mut mutex_changer = my_mutex.lock().unwarp();// 加锁后修改,也可大括号括起来,括号外自己解锁(超出加锁范围)*mutex_changer = 6;// 解锁std::mem::drop(mutex_changer);// 判断是否可用if let Ok(value) = my_mutex.try_lock(){    //没加锁}else{    // 加锁}// 直接赋值,不需要解锁*my_mutex.lock().unwarp() = 6;
  • RwLock

    1. 读写锁 类似于Mutex和RefCell

    2. 多个.read() 可以,一个.write() 可以

    use std::sync::RwLock;let my_rwlock = RwLock::new(5);let read1 = my_rwlock.read().unwrap(); // 多个read都可以let read2 = my_rwlock.read().unwrap();// 多个read都可以drop(read1); drop(read2); // 两个read()都进行了解锁,因此可以write()let mut write1 = my_rwlock.write().unwarp();*write1 = 6;drop(write1); // 解锁后可继续操作if let Ok(mut number) = my_rwlock.try_write(){    *number += 10}else{    // 锁住了}

Cow

  • 枚举,写时克隆

    // 说明: 当类型为B时,返回 Borrowed(&"a B), 否则 Owned(:Owned)pub enum Cow<"a, B> where B: "a + ToOwned + ?Size,{    Borrowed(&"a B),    Owned(:Owned),}// Cow<"static, str>判断时为// Cow::Borrowed(message) : message 为 实际值// Cow::Owned(message) : message 为 实际值//注意,返回的数值是strfn modulo_3(input: u8) -> Cow<"static, str> {    match input % 3 {        0 => "Remainder is 0".into(),        1 => "Remainder is 1".into(),        remainder => format!("Remainder is {}", remainder).into(), // 这个为String,因此会变成Cow::Owned()    }}fn main() {    for number in 1..=6 {        match modulo_3(number) {            Cow::Borrowed(message) => println!("{} went in. The Cow is borrowed with this message: {}", number, message),            Cow::Owned(message) => println!("{} went in. The Cow is owned with this message: {}", number, message),        }    }}

类型别名

  • 声明别名的几种方式及使用

    //方式一type CharacterVec = Vec;//方式二type SkipFourTakeFive<"a> = std::iter::Take>>;fn returns<"a>(input: &"a Vec) -> SkipFourTakeFive {    input.iter().skip(4).take(5)}//方式三use std::iter::{Task, Skip};use std::slice::Iter;fn returns<"a>(input: &"a Vec) -> Take>> {    input.iter().skip(4).take(5)}//方式四struct File(String); // File is a wrapper around Stringfn main() {    let my_file = File(String::from("I am file contents"));    let my_string = String::from("I am file contents");    println!("{}", my_file == my_string);  // ⚠️ 错误,不能比较,因为类型不对    println!("{}", my_file.0 == my_string);//      正确}//方式五 enum枚举简单调用enum MapDirection{    North, East,}fn main(){    use MapDirection::*;    //后面可直接使用 MapDirction    match direction{        North => println!(),        East => println!();    }    // 也可以进行改名    use MapDirection::{        North as N,        East as E,    }}

todo! 宏

  • 还未想好如何操作,但是又要运行,可以用 todo!()

    fn get_book(book: &Book) -> Option {    todo!() // todo means "I will do it later, please be quiet"}

Rc

  • 使用数量变为0,才会消失

    use std::rc:Rc;let history = Rc::new("".to_string());let h2 = history.clone() // Rc的计数变为了2println!("{}", Rc::strong_count(&history)); //强引用数量Rc::downgrade(&item) 来创建弱引用 //如果只有弱引用,则变量会消失Rc::weak_count(&item) 查看弱引用数

多线程

  • std ::thread ::spawn 创建线程

    fn main(){    //当主程序结束,线程还未结束时,会报异常    std::thread::spawn(||{        println!("");    });    // 改进 将线程绑定到变量上    let handle = std::thread::spawn(||{        println!("");    });    handle.join();        // 取值    let mut my_str = String::form("");    let handle = std::thread::spawn(move || { // 使用move来获得线程外的数值        println!("{}", my_str);    });    handle.join();}

闭包

  • FnOnce: 取整个值

  • FnMut : 取一个可变引用

  • Fn : 取一个普通引用

  • 各种方式举例

    // fn方式let my_str = String::form("string");let my_closure = || println!("{}", my_str);my_closure();   //可多次调用    my_closure(); // String没有实现copy,因此是Fn// FnMut方式let mut my_str = String::form("string");let mut my_closure = || {    my_str.push_str(" clone");    println!("{}", my_str);}my_closure();   //可多次调用,my_str会新增clone字符串my_closure();   // 如果改变my_str, 就变成了FnMut//  FnOnce方式let my_vec: Vec = vec![8, 9, 10];let my_closure = || {    my_vec    .into_iter() // into_iter takes ownership    .map(|x| x as u8) // turn it into u8    .map(|x| x * 2) // multiply by 2    .collect::>() // collect into a Vec};let new_vec = my_closure(); //只能使用一次

关键词: