rust的所有权系统 - 前端笔记-fn main() { println!({}, 所有权); // ① 所有权机制 所有权是rust的核心功能...

学习笔记

点滴记忆
回忆过往
首页>> web后端 >>rust的所有权系统 - 前端笔记
fn main() {
    println!("{}", "所有权");

    // ① 所有权机制  所有权是rust的核心功能,让rust无需实行垃圾回收机制就可以保证内存安全
    // 1. 每个变量都有一个被称为所有者(对这个变量的内存空间层删改查)
    // 2. 每个变量每一个时刻只有一个所有者
    // 3. 当所有者离开作用域,这个变量将被丢弃
    // 4. 基本类型存储在栈上 没有所有者的概念(相当于每次赋值,传值,返回值,都是新的值)
    // 5. 每次赋值,传值,返回值 都会转移所有权

    let a = 10;
    let b = a;

    println!("{}", a);
    println!("{}", b);

    let str1 = String::from("张三");
    let str2 = str1;
    // println!("{}", str1);// 报错  参考上面第四条,str1的所有权转移给str2了
    // let str2 = &str1; // 引用
    // let str2 = str1.clone(); // 克隆一份出来  不支持 copy()
    // copy 只针对 基本数据类型(只会复制栈上的值),clone() 都针对(会把栈和堆上的数据一起复制)
    // println!("{}", str1);

    println!("{}", str2);

    // ②引用 和 借用

    let vec1 = vec![1, 2, 3];
    let vec2 = vec![4, 5, 6];
    // 直接返回 所有权,不过又要赋值新变量名  不是很方便
    // fn sum_vec(v1: Vec<i32>, v2: Vec<i32>) -> (i32, Vec<i32>, Vec<i32>) {
    //     let sum1: i32 = v1.iter().sum();
    //     let sum2: i32 = v2.iter().sum();
    //     (sum1 + sum2, v1, v2)
    // }

    // 引用
    fn sum_vec(v1: &Vec<i32>, v2: &Vec<i32>) -> (i32) {
        let sum1: i32 = v1.iter().sum();
        let sum2: i32 = v2.iter().sum();
        (sum1 + sum2)
    }

    let (answer) = sum_vec(&vec1, &vec2);
    println!("{}--{:?}--{:?}", answer, vec1, vec2);
    println!("{}", format!("{}/{}", 1, 2));

    // 引用写个 &mut
    let mut vmut = vec![1, 10, 20, 30];
    fn push_vec(v: &mut Vec<i32>, value: i32) {
        println!("{}", v.is_empty());
        println!("{:?}--{:?}", v.len(), v.get(v.len() - 1));
        // unwrap() 取Some(3) 值的 必须确保 some存在不然会报错 所以先判断v 是否为空
        if v.is_empty() || v.get(v.len() - 1).unwrap() < &value {
            v.push(value)
        }
        v.push(value)
    }
    push_vec(&mut vmut, 10);
    println!("{:?}----mut", vmut);

    // 借用
    // 1. 在同一个作用域只能有 一个可变引用,和多个不可变引用
    // 2. 在可变引用释放前 不能访问资源所有者(貌似所以引用都是这样不能访问所有者)
    // 3. 任何引用的作用域都必须小于资源所有者的作用域,并离开作用域后自动释放(资源所以者都消失了,引用还有啥用 哈哈哈)

    let mut x = 6;
    let y = &mut x;

    // let z = &x; //不满足 第一条
    // println!("{}--{}", y,x); // 不满足第二条
    println!("{}", y);

    // 切片  是针对 数组,字符串...
    // 切片后就变成  &str 类型的了(本来字符串是 string类型 切片就变 &str了)
    let s = String::from("hello,rust");
    println!("{}", &s[0..5]);//hello
    println!("{}", &s[5..]);//,rust
    println!("{}", &s[0..]);//hello,rust
    fn print_str(s: &str) {
        println!("{}--{}", s.len(), s)
    }

    print_str(&s[0..2]);
    print_str(&s[0..]);

    let mut veccc = vec![1, 2, 3, 4, 5];
    let qvec = &mut veccc[0..3];
    qvec[0] = 100;

    // veccc.into_iter(); // 转移所有权迭代器 在访问  veccc 就会报错
    // veccc.iter(); // 不可变迭代器
    // veccc.iter_mut();// 可变迭代器
    for i in veccc.iter_mut() {
        println!("{:p}", i); // 这个i在这里是地址 需要* 取值才行
        *i += 100
    }
    println!("{:?}-**-*-*-", veccc);

    // ③生命周期
    // 1. 每一个引用已经包含引用的数据结构 都有一个作用域这个作用域就是生命周期
    // 2. 生命周期是隐式推断的,特殊情况下需要自己写
    // 定义生命周期:&'a i32 ,&'a mut i32,&'a str

    // 隐式生命周期
    fn foos(x: &str) -> &str {
        x
    }
    fn foo<'a>(x: &'a str) -> &'a str {
        x
    }
    // 显示生命周期
    // 编译报错,rust不知道如何处理,
    // x rust推断出是 'a
    // y rust推断出是 'b
    // 你返回的生命周期没办法推断是  'a / 'b
    // fn long_str(x: &str, y: &str) -> &str {
    //     if x.len() > y.len() {
    //         x
    //     } else {
    //         y
    //     }
    // }

    fn long_str<'a>(x: &'a str, y: &'a str) -> &'a str {
        if x.len() > y.len() {
            x
        } else {
            y
        }
    }

    // 静态生命周期 ,他是具有和整个程序运行的生命周期相同的生命周期
    // 'static      字符串字面量默认就是这种,所以推荐使用String类型的
    let str = "站事";

    // 悬垂指针就是  指针引用的无效的数据

    let str1 = String::from("abcd");
    let result;
    {
        let str2 = "xyz";
        result = long_str(str1.as_str(), str2)
    }
    println!("{}", result);

    // 1. 每一个省略的生命周期注解的参数,都具有不相同的生命周期,
    // fn foo(x:&i32) => fn foo<'a>(x:&'a i32)
    // fn foo(x:&i32,y:&i32) => fn foo<'a,'b>(x:&'a i32,y:&'b i32)

    // 2. 如果只有一个输入生命周期,这个生命周期会复制给所以省略的生命周期
    // fn foo(x:&i32)->&i32 => fn foo<'a>(x:&'a i32)->&'a i32

    // 3. 方法中的self发生命周期会赋值给所以省略的输出的生命周期

    struct aa<'a> {
        x: &'a i32,
    }
}

×

感谢您的支持,我们会一直保持!

扫码支持
请土豪扫码随意打赏

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

打赏作者
版权所有,转载注意明处:前端笔记 » rust的所有权系统

发表评论

路人甲 表情
Ctrl+Enter快速提交

网友评论(0)