Rust(9):变量的生命周期和所有权
  oS1xgoxjr0QZ 2023年11月02日 24 0

所有权是 Rust 的核心特性之一。

Rust 和其他语言相比最出色的就是安全性。这个安全性就是建立在所有权之上。

常见的内存管理机制

程序运行在内存之中,所有的编程语言都有自己的一套内存管理的机制。

对于 JSer来说,由于 V8 引擎使用的是 GC 垃圾回收机制,并不需要开发者介入,所以 JSer 对于内存的管理的概念通常会比较陌生。

下面是两种常见的内存管理机制:

  • Malloc 和 free:采用 mallocfree 机制的代表是 C 语言,需要开发者手动管理内存,使用时申请,不用时手动释放。
  • GC:采用 GC 的语言有 GolangJavaJavaScript 等。开发者只需要申请内存拿来用,不需要手动管理。垃圾回收器会自动检测可回收的内存空间,对于那些不再被使用的内存,就会被回收和释放掉。

Rust 采用了一种介于手动管理和自动管理的中间方案,既想要手动管理的高性能,又想要自动管理的易用性。

为了管理内存,Rust 引入了生命周期和所有权的概念。

生命周期

在 C 语言中需要开发者自己手动调用 free 函数去释放内存。

Rust 在编译期间会计算变量的使用范围,当变量不再被使用时,编译器会自动在源码中插入 free 代码,从而释放掉内存。这就是 Rust 中内存的生命周期。

所有权

Rust 中任何一个值都必须绑定一个变量,称之为该值的所有者

fn main() {
 let s1 = String::from("hello");
 println!("{}", s1);
}

对于这段代码,有两种描述方式:

1.创建了一个变量 s1,它的值是字符串值 hello

2.创建了一个字符串值,将其赋值给了变量,也就是该值的所有者是变量 s1

Rust 中每一个值都必须有一个所有者,同时每个值都还有自己的作用域当值离开作用域时,它所占用的内存就会被回收

比如下面这段代码,变量 s1 存在于 main 函数的作用域中,变量 s2 存在于一个块级作用域中:

fn main() {
  let s1 = String::from("string1");
  println!("{}", s1);
    
  {
    let s2 = String::from("string2");
    println!("{}", s2);
  }
}

运行代码,控制台可以分别打印出变量 s1s2 的值。

但是一旦变量 s2 离开了它所处的作用域:

fn main() {
  let s1 = String::from("string1");
  println!("{}", s1);
    
  {
    let s2 = String::from("string2");
  }

  println!("{}", s2);
}

就会报错:

Rust(9):变量的生命周期和所有权_Rust

error[E0425]: cannot find value s2 in this scope 的意思是在当前作用域内找不到 s2 的值

拿 JS 做一个对比,在 ES6 以前,JS 中只有全局作用域和函数作用域。ES6 提供了新的声明变量的关键字 let 和 const,于是 JS 中也有了块级作用域的概念。在声明变量之前是不可访问的,在作用域内声明变量之后是可以访问的,离开作用域后访问会报错,比如这段 JS 代码:

if(true) {
   console.log(a); // 报错:ReferenceError: Cannot access 'a' before initialization
   let a = 'a'; 
   console.log(a); // 'a'
}

console.log(a); // 报错:ReferenceError: a is not defined

Rust 中变量的作用域,就好比 JS 中的变量作用域一样。

如果对 Rust 变量作用域有所疑惑,看了 JS 的示例之后,应该就能理解了。

小结

这节课进一步学习了 Rust 中所有权的概念。所有权,就是每一个值都有一个对应的变量作为它的所有者。当所有者离开自己的作用域时,所占用的内存空间就会被释放。对于初学者,尤其是没有接触过内存管理的概念的人来说,还是有一定难度的。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  oS1xgoxjr0QZ   2023年11月02日   42   0   0 数组Rust
  oS1xgoxjr0QZ   2023年11月02日   32   0   0 Rust
  dBFTbkVLMBge   2023年11月02日   29   0   0 Rust
  oS1xgoxjr0QZ   2023年11月02日   39   0   0 Rust
  oS1xgoxjr0QZ   2023年11月02日   25   0   0 Rust
  oS1xgoxjr0QZ   2023年11月02日   41   0   0 Rust
  oS1xgoxjr0QZ   2023年11月02日   48   0   0 Rust
  y5zqVixaDLkE   2023年11月02日   34   0   0 RustmysqlPostgreSQL
oS1xgoxjr0QZ