banner
lee

lee

Rust 学习

Rust 学习#

基础#

  1. 变量#

    let a = 10;		// a不可变
    let mut a = 10	// a可变
    

    Rust 在变量离开作用域后,就自动释放内存,Rust 在结尾的 } 处自动调用 drop

  2. 基本类型#

    2.1 数值类型#

    语句:一个具体的操作,没有返回值

    表达式:表达式总要返回值

    fn add_with_extra(x: i32, y: i32) -> i32 {
        let x = x + 1; // 语句
        let y = y + 5; // 语句
        x + y // 表达式
    }
    
    2.2 字符、布尔、单元类型#

    String 类型:动态字符串类型,分配在堆上

    let mut s = String::from("hello");
    s.push_str(", world!")	//在字符串追加字面值
    

    Rust 中字符是 Unicode 类型,因此每个字符占据 4 个字节

    字符串是 UTF-8 编码,字符串中的字符所占的字节数是变化的 (1-4)

    • 追加(Push)

      let mut s = String::from("Hello ")
      s.push_str("rust")
      s.push('!')
      

      push ():追加字符

      push_str ():追加字符串

      两个方法都是在原有的字符串上追加,并不会返回新的字符串,所以该字符串必须是可变的,由 mut 关键字修饰

    • 插入(Insert)

      let mut s = String::from("Hello rust!")
      s.insert(5, ',')
      s.insert_str(6, " I like")
      

      字符串插入操作要修改原来的字符串,所以该字符串必须是可变的,必须由 mut 关键字修饰

    • 替换(Replace)

      replace

      let string_replace = String::from("I like rust")
      let new_string = string_replace.replace("rust", "Rust")
      

      replacen

      let s_replace = "I like rust learn rust"
      let ns_replacen = s_replace.replacen("rust", "Rust", 1)
      

      字符串替换操作要返回一个新的字符串,而不是操作原来的字符串

      replace_range:仅使用 String 类型

      let mut s_replace_range = String::from("I like rust")
      s_replace_range.replace_range(7..8, "R")
      

      该方法会直接操作原来的字符串,不会返回新的字符串,必须使用 mut 关键字修饰

    • 删除(Delete)

      pop:删除并返回最后一个字符

      let mut s_pop = String::from("rust pop 中文!")
      let p1 = s_pop.pop()
      

      该方法是直接操作原来的字符串,但是存在返回值,如果字符串是空,则返回 None

      remove:删除并返回字符串指定位置的字符

      let mut s_remove = String::from("rust remove 中文")
      string_remove.remove(0)
      

      该方法是直接操作原来的字符串,但是存在字符串

      truncate:删除字符串中从指定位置开始到结尾的全部字符

      let mut s_truncate = String::from("测试truncate")
      s_truncate.truncate(3)
      

      该方法是操作原来字符串,无返回值

      clear:清空字符串

      let mut s_clear = String::from("string clear")
      s_clear.clear()
      

      该方法是直接操作原来的字符串,等价 s_clear.truncate (0)

    • 连接(Concatenate)

      使用 + 或 += 连接字符串,要求右边的参数必须为字符串的切片引用 (Slice) 类型

      + 是返回一个新的字符串,所以变量声明可以不需要 mut 关键字修饰

    2.3 元组#
    let x : (i32, f64, u8) = (500, 6.4, 1);
    let a = x.0;
    let b = x.1;
    
    2.4 结构体#
    1. 初始化实例,每个字段都需要进行初始化
    2. 初始化字段顺序不需要和定义时的一致
    3. 当函数参数和结构体字段同名时,可以直接使用缩略方式初始化
    4. user2 仅在 email 上和 user1 不同,因此只需要对 email 赋值,剩下通过..user1
    fn build_user(email: String, username: String) -> User {
        User {
            email,
            username,
            active: true,
            sign_in_count: 1,
        }
    }
    
    let user2 = User {
        email: String::from("[email protected]")
        ..user1
    };
    

    单元结构体:不关心该类型的内容,只关心它的行为

    struct AlwaysEqual;
    let subject = AlwaysEqual;
    impl SomeTrait for AlwaysEqual {}
    

    结构体输出打印

    1. 手动实现 Display,Debug
    2. 使用派生类
    #[derive(Debug)]
    struct Rectangle {
        width: u32,
        height: u32,
    }
    println!("rect1 is {:?}", rect1)
    
    2.5 所有权和借用#
    1. Rust 中每一个值都被一个变量所拥有,改变量被称为值的所有者
    2. 一个值同时只能被一个变量所拥有,或者说一个值只能拥有一个所有者
    3. 当所有者 (变量) 离开作用域范围时,这个值将被丢弃,Rust 会自动调用 drop 函数并清理变量的堆内存
    let s1 = String::from("hello");
    let s2 = s1;
    
    println!("{}, world!", s1)
    

    s1 被赋予 s2 后,Rust 认为 s1 不再有效,因此也无需在 s1 离开作用域后 drop 任何东西,这就是把所有权 s1 转移给了 s2,s1 在被赋予 s2 后马上失效了,Rust 禁止使用无效的引用

    let x = 5;
    let y = x;
    

    首先将 5 绑定到变量 x,接着拷贝 x 的值赋给 y,最终 x 和 y 都等于 5,整数是 Rust 基本数据类型,是固定大小的简单值,因此这两个值都是通过自动拷贝的方式来赋值的,都被存在栈中,无需堆上分配内存

    2.6 引用和借用#

    获取变量的引用,称之为借用

    • 不可变引用

      fn main() {
          let s1 = String::from("hello");
          let len = calculate_len(&s1);
          println!("the len of '{}' is {}.", s1, len);
      }
      fn calculate_len(s: &String) -> usize {
          s.len()
      }
      
    • 可变引用

      fn main() {
          let mut s = String::from("hello");
          change(&mut s);
      }
      fn change(some_string: &mut String) {
          some_string.push_str(", world");
      }
      
      1. 不可变引用允许同时存在多个
      2. 可变引用同时只能存在一个
      3. 可变引用和不可变引用不能同时存在
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。