Rust,再次入门

前言

Rust是一个别扭的语言,他引入了一些概念使得程序变得安全,
https://www.bilibili.com/video/BV1bVS4YXEE5

所有权

rust中,由Box包装的变量具有所有权。
所有权的设计意义在于避免手动管理内存。函数内创建的Box变量,会在函数生命周期结束时自动释放内存。而如果不设计所有权,这个内存地址会被释放多次,导致程序崩溃。
比如first有所有权,当执行let second = first;时,所有权会转移到second上,后续代码不能再使用到first变量。

而如果是js,first和second都会获得对象的引用,二者等效。

如何转移?

理论上来说,赋值会引起所有权转移,而函数传参本身是一种赋值(实参赋值给形参)。
所以,有两种明显的所有权转移方法。

  1. 直接赋值
  2. 传入函数
fn main() {
    let first = String::from("Ferris");
    let full = add_suffix(first);
    // 数据的所有权转移到了full身上,first失效,因此会报错
    println!("{full}, originally {first}");
}

fn add_suffix(mut name: String) -> String {
    name.push_str(" Jr.");
    name
}

所以我认为,所有权的转移如下:
first -> name(函数内部参数) -> full

引用和解引用

image
当使用Box创建对象时,会在堆内存上开辟内存空间(Heap),栈内存上是内存的指针。
因此,从指针到数据之间,使用解引用来获取数据。

fn main() {
    let mut x: Box<i32> = Box::new(1);
    // 比如下面*x是简单数据1,因此直接存在栈内存上
    let a:i32 = *x;
    // *x直接访问x对应的数据,因此可以直接+=改变其值
    *x += 1;
    println!("x为:{x},a为:{a}");
    let r1: &Box<i32> = &x;
    let b: i32 = **r1;
    // &*x可以理解为&(*x),即对Heap上数据的直接引用。  
    // 在rust中这被称为借用,目的是为了和拥有所有权的x区分开。
    // 由于只有box会释放内存,因此多个引用并不会引发多次释放内存的问题
    // 所以依然是安全的
    let r2:&i32 = &*x;
    let c:i32 = *r2;
    println!("转移?:{x},a为:{a}");
}

image

这部分和c语言差不多。
image

题目

1

image
3次,上面L1这张图就是解析。

2

image
答案是第三个,因为传入函数的是&v,而&v不具有所有权,所以不会引起内存释放等问题。

例子

image

image
当执行v.push(4)时,重新分配了内存并放在了一个新的地址,然后让v指向这个地址。
然而,num依然指向原来的地址,因此引发错误。

结论

确实挺难的,太束手束脚了,感觉很痛苦。

posted @ 2025-05-25 18:05  魂祈梦  阅读(17)  评论(0)    收藏  举报