rust 【入门】05- 引用

17 阅读1分钟

use std::fmt::{Debug, Display}; use std::ops::AddAssign; use std::path::Path; use serde::de::Unexpected::Str;

/**

  • 引用:从所有权出借的,不发生移动,复制
    1. 从读写分为:只读引用,可变引用;
    1. 从资源占有分为:共享引用,独占引用
    1. 以上2者不可以发生交叉
  • 注意各个数据类型的引用
  • 引用转换,泛型在进行类型检查时,不会进行引用转换
  • 很可方法是在引用上实现的,如vec, string上调用的方法
  • 按索引取值要注意边界,否则会发生边界溢出问题, 未正好是中文字节数,也会发生panic */
pub async fn get_reference_demo() {
    let mut a = 0;
    let a1 = &a;
    println!("a1: {}", a1);
    let a2 = &mut a;

    // 引发错误,发了交叉,也即同时存在,共享引用,独占引用
    println!("a1: {}, a2: {}", a1, a2);

    let l = vec![1,2,3];
    let s = format!("hello 中文 world of  {}", a2);

    // 索引超出边界,发生panic
    // let s_ref = &s[20..];

    // 前几个字符, 性能不是最好的
    // iter, iter_mut, into_iter, 决定collect 可收集的情况
    let l_slice_1 = l.iter().take(2).collect::<Vec<&i32>>();
    println!("l_slice_1: {:?}", l_slice_1);
    let l_slice_2 = &l[..1];
    println!("l_slice_2: {:?}", l_slice_2);

    // 根据字符数,比较大小,后再收集
    let n = s.chars().count().saturating_sub(10);
    // 取出后几个字符
    // let (_, words) = s.split_at(n); // n 不是字节数,会报错
    let words = s.chars().skip(n).collect::<String>();

    println!("words: {}", words);

    // path依然是string,未发生变化AsRef转换
    fn print_path<P: AsRef<Path> + Display>(path: P) {
        println!("path: {}", path)
    }

    print_path(words);
}