Rust开发之——什么是所有权(10)

一 概述

  • 所有权的基本概念
  • 栈(Stack)与堆(Heap)的区别
  • 变量作用域与所有权
  • 变量与数据的交互方式
  • 函数与所有权

二 所有权的基本概念

2.1 概念

1
2
所有权(系统)是 Rust 最为与众不同的特性,
它让 Rust 无需垃圾回收(garbage collector)即可保障内存安全

2.2 内存管理方式

1
2
-Rust 通过所有权系统管理内存,无需垃圾回收,编译器在编译时检查内存安全,运行时无额外开销。
-与其他语言的区别:不依赖 GC 或手动释放内存,通过所有权规则确保内存安全。

2.3 所有权规则

1
2
-规则 1:每个值(Value)有且仅有一个所有者(Owner)变量。
-规则 2:当所有者变量离开作用域(Scope),该值会被自动丢弃(Drop)。

三 栈(Stack)与堆(Heap)的区别

特性
存储结构 后进先出(LIFO),固定大小数据 动态分配,大小不固定
分配效率 快(直接压栈 / 出栈) 慢(需查找空闲空间并记录地址)
访问效率 快(直接通过地址访问) 慢(需通过指针间接访问)
所有权关联 变量离开作用域时自动释放 需通过所有权规则管理释放时机

四 变量作用域与所有权

4.1 作用域

1
2
3
4
5
6
7
1、概念
作用域是一个项(item)在程序中有效的范围

2、示例
{
let s = String::from("hello"); // s 成为 "hello" 的所有者
} // s 离开作用域,String 被丢弃,内存释放

4.2 字符串类型对比

1
2
-字符串字面值(如 "hello"):存储在栈上,不可变,编译时确定内容。
-String 类型:存储在堆上,可变,运行时动态分配内存(如String::from("hello"))

五 变量与数据的交互方式

5.1 移动(Move)

1
2
3
4
5
6
7
8
9
10
11
1、场景:
当赋值或传递堆数据(如 String)时,发生所有权转移,原变量失效。

2、示例

let s1 = String::from("hello");
let s2 = s1; // s1 的所有权移动到 s2,s1 不再有效
println!("{}", s1); // 编译错误:use of moved value

3、底层实现:
仅复制栈上的指针、长度、容量,不复制堆数据,避免深拷贝性能开销。

5.2 克隆(Clone)

1
2
3
4
5
6
7
1、深拷贝:
手动调用clone()方法,复制堆上的数据,适用于需要保留原变量的场景。

2、示例:

let s1 = String::from("hello");
let s2 = s1.clone(); // 深拷贝堆数据,s1 和 s2 均可独立使用

5.3 拷贝(Copy)

1
2
-适用类型:栈上的简单类型(如整型、布尔、字符等),实现了Copy trait。
-特性:赋值或传递时复制值,原变量仍有效(无需移动所有权)。

六 函数与所有权

6.1 参数传递

1
2
-传递堆数据(如 String)时,所有权转移给函数参数,函数结束后参数被丢弃。
-传递栈数据(如 i32)时,复制值,原变量仍可用(因实现Copy)

6.2 返回值

1
2
3
4
5
6
7
8
1、概念
函数返回值会将所有权转移给调用者。

2、示例:
fn gives_ownership() -> String {
String::from("hello") // 所有权转移给调用者
}
let s = gives_ownership(); // s 获得返回值的所有权

七 参考

  • Rust中文官网——什么是所有权?