Rust 教程 目录

Rust 所有权系统

什么是所有权?

所有权是 Rust 的核心特性之一,它决定了如何管理内存以及何时释放内存。Rust 使用所有权系统来保证程序的安全性和高效性,而无需像 C 或 C++ 那样依赖于手动管理内存。所有权系统由以下几部分组成:

  • 所有权
  • 借用
  • 生命周期

所有权规则

Rust 有三个核心的所有权规则,理解这些规则对于编写有效的 Rust 代码至关重要:

  1. 在一个作用域内的每一个值都有一个所有者。
  2. 值在同一时间只能有一个所有者。
  3. 当所有者离开作用域,这个值将被丢弃。

所有权与变量绑定

当一个值被赋予一个变量时,这个变量就成为了该值的所有者。例如:

在这个例子中,s 是字符串字面量 "hello" 的所有者。一旦 s 离开作用域,这个字符串字面量就会被丢弃。然而,字符串字面量实际上是在编译时被静态分配的内存,因此不会真正地被丢弃。

所有权转移

当一个值赋给另一个变量时,原来的变量不再拥有这个值。这被称为所有权转移。例如:

在上面的例子中,s1 将其拥有的 String 值转移给了 s2。之后尝试访问 s1 将导致编译错误,因为 s1 已经失去了对 String 的所有权。

所有权与函数

当一个值作为参数传递给函数时,该值的所有权也会转移给函数。例如:

-- -------------------- ---- -------
-- ------ -
    --- - - ----------------------
    ------------------- -- --- ----------
    
    --- - - --
    -------------- -- --- ---------
-

-- ---------------------------- ------- - -- ----------- -----
    -------------- -------------
- -- ----------- -------- ------------- ---

-- ------------------------ ---- - -- ------------ -----
    -------------- --------------
- -- ------------ --------------- ---- ----- -----------
展开代码

在这个例子中,s 的所有权被传递给 takes_ownership 函数,因此在函数内部可以安全地使用 s。而在 makes_copy 函数中,由于 i32 类型实现了 Copy trait,它的值被复制了一份传递给函数,因此原始值 x 仍然有效。

返回值与所有权

函数也可以返回一个值的所有权。例如:

-- -------------------- ---- -------
-- ------ -
    --- -- - ------------------ -- ----------------- ------------ ----
    
    --- -- - ----------------------
    --- -- - ------------------------- -- ---- -------- ---------------------- --------- ----
-

-- ----------------- -- ------ - -- ----------------- ---------------
    --- ----------- - ----------------------
    -----------
-

-- ------------------------------ ------- -- ------ - -- ---------- -------- ---------------------- --
    --------
-
展开代码

在这个例子中,gives_ownership 函数创建了一个新的 String 并将其所有权转移给调用者。takes_and_gives_back 函数接受一个 String 参数,并将其所有权再次转移给调用者。

引用与借用

引用允许我们访问一个值而不获取其所有权。这有助于避免所有权转移带来的复杂性,并且可以在不转移所有权的情况下共享数据。引用分为不可变引用和可变引用两种类型。

不可变引用

不可变引用通过 & 符号来创建。例如:

-- -------------------- ---- -------
-- ------ -
    --- - - ----------------------
    --- --- - --------------------- -- ---------
    
    ------------- ------ -- ---- -- ----- -- -----
-

-- ------------------- -------- -- ----- - -- --- ----- -------- ------
    -------
-
展开代码

在这个例子中,calculate_length 函数接受一个不可变引用作为参数。这允许我们在不转移所有权的情况下计算 String 的长度。

可变引用

可变引用通过 &mut 符号来创建。一个值在任何时刻只能有一个可变引用。例如:

-- -------------------- ---- -------
-- ------ -
    --- --- - - ----------------------
    ----------- --- -- --------
    
    -------------- ---
-

-- ------------------- ---- ------- - -- ------------- ----- -------- -----
    ----------------------- --------
-
展开代码

在这个例子中,change 函数接受一个可变引用作为参数。这允许我们在不转移所有权的情况下修改 String 的内容。

生命周期

生命周期确保引用总是有效的。Rust 编译器会自动推断大多数引用的生命周期,但在某些情况下需要显式指定。生命周期注解通常放在引用类型的前面。例如:

-- -------------------- ---- -------
-- -------------- --- ---- -- --- ---- -- --- --- - -- ---- ---------
    -- ------- - ------- -
        -
    - ---- -
        -
    -
-

-- ------ -
    --- ------- - ------------------ ------ -- -------
    -
        --- ------- - --------------------
        --- ------ - ------------------------- ------------------
        ------------- ------- ------ -- ---- --------
    -
-
展开代码

在这个例子中,longest 函数接受两个引用,并返回一个引用。生命周期注解 'a 确保返回的引用始终有效。

总结

本章介绍了 Rust 的所有权系统,包括所有权、借用和生命周期的概念。理解这些概念对于编写高效的 Rust 代码至关重要。通过所有权转移、引用和生命周期注解,Rust 提供了一种安全且高效的方式来管理内存。

上一篇: Rust loop无限循环
下一篇: Rust 变量作用域
纠错
反馈

纠错反馈