Rust 笔记Rust 语言中的运算符
作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343
本文地址:https://blog.csdn.net/qq_28550263/article/details/131013679
【介绍】:本文讲解 Rust 语言中的运算符。
上一节:《 暂无》 | 下一节:《 在 Rust 语言中使用重载 》
目 录
1. 概述
在各种编程语言中,运算符(Operators)是用于执行各种操作的符号或关键字。它们可以用于操作数据、执行逻辑判断、进行赋值等。根据其功能和操作数的数量,运算符可以被分类为以下几种类型:
- 一元运算符:一元运算符作用于单个操作数,对其进行特定操作或计算。
- 二元运算符:二元运算符作用于两个操作数,对其进行特定操作或计算。
- 三元运算符:三元运算符是一种特殊的运算符,接受三个操作数,并根据第一个操作数的条件返回第二个或第三个操作数。
注:Rust 语言中无三元运算符。
- 逻辑运算符:逻辑运算符用于执行逻辑操作,例如逻辑与、逻辑或和逻辑非。
- 比较运算符:比较运算符用于比较两个值之间的关系,并返回布尔值(true 或 false)。
- 算术运算符:算术运算符用于执行数学运算,如加法、减法、乘法和除法等。
- 位运算符:位运算符用于对二进制位进行操作,如按位与、按位或、按位异或等。
- 索引运算符:它需用于从 被索引的操作数 凭借 索引值 获取结果返回。
以上的类别是有重叠的,比如 逻辑运算符 等也是一元运算符, 算术运算符、索引运算符 等同时也是 二元运算符。在本文的介绍中,如果在前面的类别中已经讲解过,则后文不再重复讲解。
2. 一元运算符
2.1 关于 一元运算符
一元运算符(Unary Operators)又称之为单目运算符,指的是只对一个表达式执行操作,该表达式可以是数值数据类型类别中的任何一种数据类型。Rust 语言 中的一元运算符包括 加(+)、减(-)、**逻辑非(!)**和 取地址(&) 等。但是整体上看,都可以视为一元或者二元运算符,并且 rust 语言不提供内置的三元操作符。
2.2 正(+)运算符
【注意】:+ 用于 取正 时为 一元运算符,但是用于 加法 时则为 二元运算符。另请参见 [加运算符
加(+) 运算符 用于对操作数 取正,其实没有实际变化。
let a = 10; let b = +a; // 取 a 的正值(实际上没有变化) println!("b: {}", b); // 输出: b: 10
2.3 负(-)运算符
负(-) 运算符 用于用于对操作数取负。例如:
let a = 10; let b = -a; // 取 a 的负值 println!("b: {}", b); // 输出: b: -10
2.4 逻辑非(!)运算符
逻辑非(!) 运算符 用于 对 布尔类型 的操作数 取反。包括以下两种情况:
- 如果操作数的值为
true
,则将true
变为false
; - 如果操作数的值为
false
,则将false
变为true
例如:
let a = true; let b = !a; // 对 a 取逻辑非 println!("b: {}", b); // 输出: b: false
2.5 递增(++)和递减(–)运算符
递增(++) 和 **递减(–)**运算符 分别用于 对操作数 进行 自增 和 自减 操作。例如:
// 自增操作 let mut a = 10; a += 1; // 等价于 a = a + 1 println!("a: {}", a); // 输出: a: 11 // 自减操作 let mut b = 5; b -= 1; // 等价于 b = b - 1 println!("b: {}", b); // 输出: b: 4
2.6 取址(&)运算符
取址(&) 运算符用于 获取变量的内存地址。例如:
let a = 10; let b = &a; // 获取变量 a 的内存地址 println!("b: {:?}", b); // 输出: b: 0x7ffc8680d1b8(具体的地址可能不同)
2.7 解引用(*)运算符
解引用运算符 *
用于从 引用类型 中获取 引用所指向的值。它允许你访问引用类型中存储的实际值。
例如:
let num = 42; let num_ref = # let dereferenced_num = *num_ref; // 使用解引用运算符获取引用所指向的值 println!("Dereferenced num: {}", dereferenced_num); // 输出: Dereferenced num: 42 let mut value = 10; let value_ref = &mut value; *value_ref = 20; // 使用解引用运算符修改引用所指向的值 println!("Modified value: {}", value); // 输出: Modified value: 20
3. 二元运算符
3.1 关于 二元运算符
类似地,二元运算符(Binary Operators)是一种作用于两个操作数的运算符。在各种编程语言中一般用于表示由两个元素形成第三个元素的一种规则,它们往往用于执行各种操作,如加法、减法、乘法、除法、逻辑运算等。
在 Rust 语言中,对二元运算符进行细分还可以分为:
- 算术运算符:用于执行数值计算;
- 逻辑运算符:用于执行逻辑操作;
- 赋值运算符:用于将 右侧的值 赋给 左侧的变量;
- 比较运算符:用于对两个值进行比较并得出结论;
3.2 算术运算符
3.2.1 加法(+)运算符
加法(+) 运算符用于对两个操作数进行相加。例如:
let a = 5; let b = 3; let c = a + b; // 将 a 和 b 相加 println!("c: {}", c); // 输出: c: 8
3.2.1 减法(-)运算符
减法(-) 运算符用于从第一个操作数中减去第二个操作数。例如:
let a = 5; let b = 3; let c = a - b; // 从 a 中减去 b println!("c: {}", c); // 输出: c: 2
3.2.3 乘法(*)运算符
乘法(*) 运算符用于将两个操作数相乘。例如:
let a = 5; let b = 3; let c = a * b; // 将 a 和 b 相乘 println!("c: {}", c); // 输出: c: 15
3.2.3 除法(/)运算符
除法(/) 运算符用于将第一个操作数除以第二个操作数。例如:
let a = 10; let b = 2; let c = a / b; // 将 a 除以 b println!("c: {}", c); // 输出: c: 5
3.3 逻辑运算符
3.3.1 逻辑与(&&)
逻辑与(&&) 运算符 用于对两个布尔类型的操作数进行逻辑与操作。例如:
let a = true; let b = false; let c = a && b; // 对 a 和 b 执行逻辑与操作 println!("c: {}", c); // 输出: c: false
3.3.2 逻辑或(||)
逻辑或(||) 运算符用于对两个布尔类型的操作数进行逻辑或操作。例如:
let a = true; let b = false; let c = a || b; // 对 a 和 b 执行逻辑或操作 println!("c: {}", c); // 输出: c: true
3.4 比较运算符
3.4.1 等于(==)
相等性(==) 运算符用于检查两个操作数是否相等。例如:
let a = 2; let b = 2; let c = a == b; // 检查 a 和 b 是否相等 println!("c: {}", c); // 输出: c: true
3.4.2 不等于(!=)
不相等(!=) 运算符用于检查两个操作数是否不等。例如:
let a = 1; let b = 3; let c = a != b; // 检查 a 和 b 是否不相等 println!("c: {}", c); // 输出: c: true
3.4.3 大于运算符(>)
大于运算符(>) 用于检查左操作数是否大于右操作数。
let a = 2; let b = 1; let result = a > b; // 结果为 true
3.4.4 小于运算符(<)
小于运算符(<) 用于 检查左操作数是否小于右操作数。例如:
let a = 2; let b = 1; let result = a < b; // 结果为 false
3.4.5 大于等于运算符(>=)
大于等于运算符(>=) 用于检查左操作数是否大于或等于右操作数。例如:
let a = 2; let b = 1; let result = a >= b; // 结果为 true
3.4.6 小于等于运算符(<=)
小于等于运算符(<=) 用于检查左操作数是否小于或等于右操作数。例如:
let a = 2; let b = 1; let result = a <= b; // 结果为 false
3.5 赋值运算符
3.5.1 基本赋值(=)运算符
赋值(=) 运算符 用于将右侧的值赋给左侧的变量。例如:
let a = 1; // 将值 1 赋给变量 a
3.5.2 复合赋值运算符(如 +=、-=、*=、/= 等)
在赋值运算符的基础上,结合其它运算符就形成了功能略多的 复合赋值运算符(如 +=、-=、*=、/= 等)。 复合赋值运算符用于将运算符右侧的值与左侧的变量进行运算,并将结果赋给左侧的变量。
let mut a = 1; a += 2; // 等价于 a = a + 2 println!("a: {}", a); // 输出: a: 3
3.6 位运算符
位运算符用于对整数类型的二进制位进行操作,也有两个操作数,因此同样可视为二元运算符。在 Rust 语言中,位运算符包括:
- 按位与运算符(&)
- 按位或运算符(|)
- 按位异或运算符(^)
- 左移运算符(<<)
- 右移运算符(>>)
3.6.1 按位与(&
)运算符
按位与运算符(&)用于对两个操作数的对应二进制位进行与操作,结果为每个对应位都为1时才为1,否则为0。
let a = 2; let b = 3; let result = a & b; // 对 a 和 b 的二进制位进行与操作
3.6.2 按位或(|
)运算符
按位或运算符(|)用于对两个操作数的对应二进制位进行或操作,结果为每个对应位都为0时才为0,否则为1。
let a = 5; let b = 3; let result = a | b; // 对 a 和 b 的二进制位进行或操作
3.6.3 按位异或(^
)运算符
按位异或运算符(^)用于对两个操作数的对应二进制位进行异或操作,结果为每个对应位相同为0,不同为1。
let a = 5; let b = 3; let result = a ^ b; // 对 a 和 b 的二进制位进行异或操作
3.6.4 左移(<<
)运算符
左移运算符(<<)用于将操作数的二进制位向左移动指定的位数,右侧空出的位用0填充。
例如:
let a = 5; // 二进制表示为 0101 let result = a << 2; // 将二进制位左移2位,结果为 10100,即 20
3.6.5 右移(>>
)运算符
右移运算符(>>)用于将操作数的二进制位向右移动指定的位数,左侧空出的位用0或符号位填充(取决于操作数的符号)。
例如:
let a = 5; // 二进制表示为 0101 let result = a >> 1; // 将二进制位右移1位,结果为 0010,即 2
3.7 索引([]
)运算符
索引运算符 []
被视需要两个操作数:被索引的数据结构 和 索引值。其中,被索引的数据结构 是 左操作数,索引值 是 右操作数。通过将索引值放在方括号内,可以使用索引运算符访问数据结构中的特定元素。被索引的数据结构 可以是很多种,比如数组、向量、字符串等等。
3.7.1 数组的索引
Rust 数组内置索引能力,可以通过索引运算符按照位序获取元素。例如:
let arr = [1, 2, 3, 4, 5]; let element = arr[2]; // 获取索引为2的元素,结果为3 arr[3] = 10; // 修改索引为3的元素为10
3.7.2 向量的索引
Rust 向量内置索引能力,可以通过索引运算符按照位序获取元素。例如:
let vec = vec![1, 2, 3, 4, 5]; let element = vec[3]; // 获取索引为3的元素,结果为4 vec[1] = 7; // 修改索引为1的元素为7
3.7.3 字符串的索引
《Rust 语言中的字符串》 中详细介绍了 str 和 String。其中我们说过字符串类型 str 是一种不可变的的字符,这种字符串类型 不支持通过索引运算符直接对其进行索引。这是因为 str 类型是一个不固定长度的 UTF-8 字符串,直接通过索引访问可能会导致不正确的操作。
好在 Rust 语言中还有一种可变字符串String。String 类型是支持通过索引运算符对其进行索引的。它可以使用索引运算符 []
并传递一个整数索引来访问 String 中的字符。例如:
let mut s = String::from("Hello, Rust!"); // 通过索引访问和修改字符 let first_char = s[0]; s[7] = 'W'; println!("First character: {}", first_char); println!("Modified string: {}", s);
3.8 调用(()
)运算符
调用运算符 () 用于调用函数或方法,将函数或方法名称与一对括号组合在一起,允许你执行函数或方法并传递参数。
例如我们可以定义一个独立的函数,或者在结构体中定义一个方法:
fn hello(name: &str) { println!("Hello, {}!", name); } struct Person { name: String, } impl Person { fn greet(&self) { println!("Hello, {}!", self.name); } }
然后在需要使用的地方通过 调用运算符 调用它们:
fn main() { hello("Alice"); // 调用函数 // 调用方法 let person = Person { name: String::from("Bob"), }; person.greet(); // 输出:Hello, Bob! }
调用运算符 () 可以用于任何 可调用项,包括函数、方法、闭包等。它可以带有参数,用于向被调用项传递值。
3.9 解引用赋值(*=
)运算符
解引用赋值运算符(*=
)是一种 复合运算符,它由之前介绍过的 解引运算符 和 赋值运算符 复合而成。
*=
用于 解引用一个可变引用,并将 新的值 赋给 引用所指向的位置。它将 右侧的值解引用,并将 解引用后的值 赋给 左侧的可变引用。 例如:
let num = 42; let num_ref = # // 使用解引用运算符获取引用所指向的值 let dereferenced_num = *num_ref; println!("Dereferenced num: {}", dereferenced_num); // 输出: Dereferenced num: 42 let mut value = 10; let value_ref = &mut value; // 使用解引用运算符修改引用所指向的值 *value_ref = 20; println!("Modified value: {}", value); // 输出: Modified value: 20