• 作者:老汪软件技巧
  • 发表时间:2024-10-03 07:00
  • 浏览量:

在Rust中,变量的声明、初始化绑定赋值是密切相关的概念,它们有一些细微的区别和特定的含义。

变量声明是在程序中引入一个新的变量名。在Rust中,变量声明通常使用 let 关键字。如下所示。

let x;  // 变量声明

变量初始化是给变量赋予一个初始值的过程。在Rust中,初始化通常在声明的同时完成。初始化标志着变量生存期的开始。变量的生存期,指变量从完成声明和初始化开始,到变量因所有权移动、被显式释放或离开作用域而结束的这段时间。

如下所示。

let x = 5;  // 变量声明并初始化,即创建一个绑定

❗️变量初始化避坑指南

变量只能被初始化一次。

**变量绑定结合了声明和初始化的概念。**在Rust中,变量"绑定"这个术语更为常用。当"绑定一个变量"时,通常指的是声明一个变量并将其与一个值关联起来。如上所示。上面这行代码将变量名 x 绑定到值 5 上。

在很多语言中,变量可以先声明后初始化。在Rust中,虽然可以将变量的声明和初始化分开(适用于变量在声明时无法立即确定其值,或变量的初始值需要通过某些计算或函数调用而得到的场景),但在使用变量之前,必须确保它已被初始化。Rust编译器会跟踪变量是否被初始化,以确保在使用前已经初始化。如下所示。

let x;      // 声明不可变变量x
x = 5;      // 初始化x,貌似为不可变变量赋值,但其实不是
println!("{}", x);  // 使用

❗️变量初始化避坑指南

当变量的声明和初始化分开时,初始化不要求变量是可变的。

**赋值是将一个新值存储到已经声明并初始化的可变变量中的过程。**可以多次进行赋值。赋值操作不会改变变量的类型。赋值可以发生在变量生存期内的任何时候。如下所示。

let mut x = 5;
x = 10; // 赋新值

❗️变量赋值避坑指南

只有可变变量才能被赋值。

在Rust中,绑定不仅仅是声明和初始化。它还涉及所有权(ownership)的概念。当绑定一个值到变量时,该变量成为这个值的唯一所有者。

Rust允许重新绑定同名变量,这被称为"遮蔽"(详见3.3)。

默认情况下,Rust中的绑定是不可变的。要创建可变绑定,需要使用 mut 关键字。如下所示。

let mut y = 5;  // 可变绑定
y = 6;          // 允许用赋值语句修改

_变量可变的是_变量定义为可变类型

Rust在绑定时可以进行类型推断,但也允许显式指定类型。如下所示。

let z = 5;       // 整型类型推断默认为 i32
let w: f64 = 5.0;  // 显式指定类型64位浮点数

在Rust中,绑定有明确的生存期,通常持续到变量离开作用域后结束。

变量绑定和赋值可能会涉及所有权的转移,特别是对于非复制(non-Copy)类型的值。

3.1.2 误为不可变结构体字段赋值

**结构体是Rust中用于创建自定义数据类型的一种方式。**它允许程序员将多个相关的值组合成一个有意义的组。当需要改结构体内某个字段的值的时候,会踩什么可变性的坑?代码清单3-2就是一个踩坑的例子。

代码清单3-2 误为不可变结构体字段赋值

// 源代码位置:ch03/immutable_field_mishap
 1 struct Point {
 2     x: i32,
 3     y: i32,
 4 }
 5 
 6 fn main() {
 8     let point = Point { x: 0, y: 0 };
10 
11     // point.x = 5;  // 取消注释这行以查看编译错误
42 }

代码清单3-2所对应的完整源代码,演示了三种情况:不可变结构体字段的赋值错误、使用可变结构体正确修改字段,以及使用RefCell实现内部可变性。代码的主旨是展示"误为不可变结构体字段赋值"的问题及其解决方法。

第1-4行定义了一个名为Point的结构体,包含两个i32类型的字段x和y。

第8行创建一个不可变的Point实例point,初始化x和y坐标为0。这是踩坑的起点。

第11行踩坑了。这行被注释掉的代码试图用赋值,修改不可变结构体实例point的x坐标,如果取消注释,将导致编译错误。

如何修复这个问题?代码清单3-2所对应的完整源代码,给出了两种修复方法。

第一种方法是在第8行实例point前面,添加mut关键字,使其变为可变实例。

❗️结构体可变性避坑指南

默认情况下,结构体实例是不可变的。要创建可变的结构体实例,需要在声明结构体变量时使用 mut 关键字。结构体的可变性是整体的,不能只将某个字段标记为可变。

第二种方法是在保持point实例不可变的情况下,将其用智能指针RefCell包裹起来。然后利用RefCell的内部可变性,来改变不可变结构体实例point内部字段的值。

❗️在不可变上下文中改变数据的避坑指南

一个不可变变量所拥有的的数据,并不是完全不能修改。使用内部可变性,是能够实现在不可变上下文中改变数据的。内部可变性是 Rust 中的一种设计模式,它允许程序员在拥有不可变引用、不可变变量或不可变实例时改变数据。这看似违反了 Rust 的借用规则,但实际上并不是这样。内部可变性是在语言的安全保证内提供了一种受控的方式来实现可变性。RefCell 、 Cell 、Mutex和RwLock是实现内部可变性的常用智能指针类型。

如果喜欢这篇文章,别忘了给文章点个“在看” ,好鼓励小吾继续写哦~