Rust开发笔记 | 所有权系统及其对内存管理的影响

Rust 是一门以系统编程为主要应用场景的编程语言,它提供了无需垃圾回收机制就能安全实现内存管理的特性。其中,所有权(Ownership)系统是 Rust 语言最核心的特点之一,它能够保证内存安全,同时避免数据竞争。下面,我们将深入探究 Rust 中所有权的概念、规则以及它与借用和切片所起到的作用。

所有权的基本原则

在 Rust 中,所有权系统基于三个基本原则:

  1. 每一个值在 Rust 中都有一个被称为其'所有者'的变量。
  2. 值在任一时刻只能有一个所有者。
  3. 当所有者超出作用域时,该值会被自动丢弃(drop)。

所有者和作用域

例如:

rust 复制代码
{
    let s = String::from("hello"); // s 进入作用域
}                                  // s 超出作用域,同时 `String` 类型的内置方法 drop 被自动调用,内存被释放

此时,s"hello" 这段数据的所有者。当 s 超出花括号包围的区域,它就超出了作用域,Rust 自动为我们调用 drop 函数,释放内存。

变量与数据交互的方式:移动(Move)

rust 复制代码
let s1 = String::from("hello");
let s2 = s1;

在这个例子中,s1 的数据似乎被复制给了 s2。然而,在 Rust 中,这里会发生所谓的移动 。事实上,s1 的所有权被移动到 s2,之后 s1 将无效且不能再被使用。

借用(Borrowing)

借用是 Rust 用来允许你使用某个值,但不取得其所有权的机制。通过引用(&T)的方式实现,可以是不可变引用或可变引用:

不可变引用

rust 复制代码
fn main() {
    let s1 = String::from("hello");
    calculate_length(&s1);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

此时,s1 将一个指向 String 的不可变引用传递给函数 calculate_length,但并不放弃所有权。

可变引用

rust 复制代码
fn main() {
    let mut s = String::from("hello");
    change(&mut s);
}

fn change(some_string: &mut String) {
    some_string.push_str(", world");
}

在这里,我们使用可变引用 &mut String 来修改 s。借出的期间内,原变量的所有权并未改变,只是暂时允许别的代码片段对数据进行修改。

注意:在特定作用域中的特定数据只能有一个活跃的可变引用,以防止数据竞争。不可变引用则可以有多个,但不能与可变引用同时存在。

切片(Slices)

切片类型让你可以引用集合中一段连续的元素序列,而不用引用整个集合。例如,对字符串切片:

rust 复制代码
fn main() {
    let s = String::from("hello world");
    let hello = &s[0..5];
    let world = &s[6..11];
}

这里 helloworld 是切片,它们引用了原字符串 s 的一部分数据。与前面的引用一样,切片也不拥有实际的数据,只是临时借用。

所有权、借用和切片共同作用于 Rust 的内存管理中,它们确保了内存安全,防止了例如空指针、悬垂指针等一系列问题的发生。此外,所有权系统使得 Rust 无需垃圾回收机制,从而使程序性能得到提升。通过学习与深入理解这些概念,开发者能够写出更安全、高效的 Rust 代码。

相关推荐
doiito2 小时前
【Agent Harness】Gliding Horse 本体论系统设计:给 AI Agent 装上“语义大脑”
ai·rust·架构设计·系统设计·ai agent
大卫小东(Sheldon)1 天前
Rust 推荐使用宏而非普通函数的场景
rust
doiito1 天前
【Agent Harness】为什么我把 JSON‑LD “编译成 DAG” 后,整个 Agent 平台立刻聪明了
ai·rust·架构设计·系统设计·ai agent
jump_jump1 天前
为了重玩金庸群侠传,我研究了一下 Ruffle 怎么复活 Flash
游戏·rust·github
LinXunFeng2 天前
Obsidian - 使用 Share Note 分享笔记并自部署
前端·笔记·github
星栈2 天前
Dioxus 多页面怎么做:`dioxus-router`、嵌套路由、`Outlet` 和页面组织,一篇给你讲顺
前端·rust·前端框架
Rust研习社4 天前
组合真的优于继承吗?为什么 Rust 和 Go 都拥抱组合舍弃继承?
后端·rust·编程语言
红尘散仙5 天前
想写一个像样的终端 App?试试把 React 的开发体验搬进 Rust TUI
前端·rust
vivo互联网技术5 天前
从 Web 到桌面:基于 Tauri 2.0 + Vue 3 打造 vivo 线下门店「大头贴」拍照体验系统
前端·rust
Rust研习社5 天前
这 8 个 Rust 学习资源值得每个新手收藏起来
后端·rust·编程语言