在 Rust 中,运算符是用于对数据执行操作的特殊符号。它们可以对操作数进行算术运算、逻辑判断、位操作等。
算术运算符
算术运算符用于执行基本的数学运算,包括加法、减法、乘法、除法和取模。以下是一些常见的算术运算符及其用法:
1.加法运算符(+
)
加法运算符用于将两个操作数相加。
rust
fn main() {
let a = 10;
let b = 5;
let sum = a + b;
println!("{} + {} = {}", a, b, sum); // 输出:10 + 5 = 15
}
2.减法运算符(-
)
减法运算符用于从一个操作数中减去另一个操作数。
rust
fn main() {
let a = 10;
let b = 5;
let difference = a - b;
println!("{} - {} = {}", a, b, difference); // 输出:10 - 5 = 5
}
3.乘法运算符(*
)
乘法运算符用于将两个操作数相乘。
rust
fn main() {
let a = 10;
let b = 5;
let product = a * b;
println!("{} * {} = {}", a, b, product); // 输出:10 * 5 = 50
}
4.除法运算符(/
)
除法运算符用于将一个操作数除以另一个操作数。如果操作数是整数,结果将被截断为整数。
rust
fn main() {
let a = 10;
let b = 5;
let quotient = a / b;
println!("{} / {} = {}", a, b, quotient); // 输出:10 / 5 = 2
}
如果操作数是浮点数,结果将保留小数部分:
rust
fn main() {
let a = 10.0;
let b = 5.0;
let quotient = a / b;
println!("{} / {} = {}", a, b, quotient); // 输出:10.0 / 5.0 = 2.0
}
5.取模运算符(%
)
取模运算符用于计算两个操作数相除后的余数。
rust
fn main() {
let a = 10;
let b = 3;
let remainder = a % b;
println!("{} % {} = {}", a, b, remainder); // 输出:10 % 3 = 1
}
注意:Rust 不支持自增(++
)和自减(--
)运算符。
比较运算符
比较运算符用于比较两个操作数的大小或相等性。它们返回一个布尔值(true
或false
)。
1.等于(==
)
用于判断两个操作数是否相等。
rust
fn main() {
let a = 10;
let b = 10;
println!("{} == {} 的结果是 {}", a, b, a == b); // 输出:10 == 10 的结果是 true
}
2.不等于(!=
)
用于判断两个操作数是否不相等。
rust
fn main() {
let a = 10;
let b = 5;
println!("{} != {} 的结果是 {}", a, b, a != b); // 输出:10 != 5 的结果是 true
}
3.大于(>
)
用于判断第一个操作数是否大于第二个操作数。
rust
fn main() {
let a = 10;
let b = 5;
println!("{} > {} 的结果是 {}", a, b, a > b); // 输出:10 > 5 的结果是 true
}
4.小于(<
)
用于判断第一个操作数是否小于第二个操作数。
rust
fn main() {
let a = 10;
let b = 5;
println!("{} < {} 的结果是 {}", a, b, a < b); // 输出:10 < 5 的结果是 false
}
5.大于等于(>=
)
用于判断第一个操作数是否大于等于第二个操作数。
rust
fn main() {
let a = 10;
let b = 5;
println!("{} >= {} 的结果是 {}", a, b, a >= b); // 输出:10 >= 5 的结果是 true
}
6.小于等于(<=
)
用于判断第一个操作数是否小于等于第二个操作数。
rust
fn main() {
let a = 10;
let b = 5;
println!("{} <= {} 的结果是 {}", a, b, a <= b); // 输出:10 <= 5 的结果是 false
}
逻辑运算符
逻辑运算符用于对布尔值进行逻辑操作,返回布尔值。
1.逻辑与(&&
)
逻辑与运算符用于判断两个条件是否都为true
。
rust
fn main() {
let a = 10;
let b = 5;
println!("{} > 5 && {} < 20 的结果是 {}", a, b, a > 5 && b < 20); // 输出:10 > 5 && 5 < 20 的结果是 true
}
2.逻辑或(||
)
逻辑或运算符用于判断两个条件中是否至少有一个为true
。
rust
fn main() {
let a = 10;
let b = 5;
println!("{} > 5 || {} < 2 的结果是 {}", a, b, a > 5 || b < 2); // 输出:10 > 5 || 5 < 2 的结果是 true
}
3.逻辑非(!
)
逻辑非运算符用于对布尔值取反。
rust
fn main() {
let a = 10;
println!("!( {} > 5 ) 的结果是 {}", a, !(a > 5)); // 输出:!( 10 > 5 ) 的结果是 false
}
位运算符
位运算符用于对操作数的二进制位进行操作。它们通常用于底层编程和性能优化。
1.按位与(&
)
按位与运算符对两个操作数的每一位执行布尔与操作。
rust
fn main() {
let a = 0b0011; // 二进制表示 3
let b = 0b0101; // 二进制表示 5
let result = a & b;
println!("{} & {} 的结果是 {}", a, b, result); // 输出:3 & 5 的结果是 1
}
2.按位或(|
)
按位或运算符对两个操作数的每一位执行布尔或操作。
rust
fn main() {
let a = 0b0011; // 二进制表示 3
let b = 0b0101; // 二进制表示 5
let result = a | b;
println!("{} | {} 的结果是 {}", a, b, result); // 输出:3 | 5 的结果是 7
}
3.按位异或(^
)
按位异或运算符对两个操作数的每一位执行布尔异或操作。如果两个位不同,则结果为1
,否则为0
。
rust
fn main() {
let a = 0b0011; // 二进制表示 3
let b = 0b0101; // 二进制表示 5
let result = a ^ b;
println!("{} ^ {} 的结果是 {}", a, b, result); // 输出:3 ^ 5 的结果是 6
}
4.按位取反(!
)
按位取反运算符对操作数的每一位取反。
rust
fn main() {
let a = 0b0011; // 二进制表示 3
let result = !a;
println!("!{} 的结果是 {}", a, result
赋值运算符
(一)基本赋值运算符(=
)
基本赋值运算符用于将右侧的值赋给左侧的变量。这是 Rust 中最常用的赋值方式。
rust
fn main() {
let mut x = 5; // 将值 5 赋给变量 x
println!("x = {}", x); // 输出:x = 5
}
(二)复合赋值运算符
复合赋值运算符结合了算术运算符和赋值操作,用于简化代码逻辑。Rust 提供了以下复合赋值运算符:
运算符 描述 示例 等价于
+=
加法赋值 x += 3;
x = x + 3;
-=
减法赋值 x -= 3;
x = x - 3;
*=
乘法赋值 x *= 3;
x = x * 3;
/=
除法赋值 x /= 3;
x = x / 3;
%=
取余赋值 x %= 3;
x = x % 3;
例如:
rust
fn main() {
let mut x = 5;
x += 3; // 等价于 x = x + 3;
println!("x = {}", x); // 输出:x = 8
x -= 2; // 等价于 x = x - 2;
println!("x = {}", x); // 输出:x = 6
x *= 2; // 等价于 x = x * 2;
println!("x = {}", x); // 输出:x = 12
x /= 3; // 等价于 x = x / 3;
println!("x = {}", x); // 输出:x = 4
x %= 2; // 等价于 x = x % 2;
println!("x = {}", x); // 输出:x = 0
}
(三)赋值运算符的特性
• 所有权转移:如果赋值的值类型不实现Copy
特性,赋值会将值的所有权从源移动到目标。例如:
rust
fn main() {
let s1 = String::from("Hello");
let s2 = s1; // s1 的所有权被移动到 s2
// println!("{}", s1); // 错误:s1 的值已被移动
println!("{}", s2); // 输出:Hello
}
不可链式赋值:Rust 不支持链式赋值(如a = b = 3
)。每次赋值操作必须独立完成。
问号运算符(?
)
问号运算符用于简化错误处理逻辑。它通常用于处理Result
和Option
类型,当遇到Err
或None
时,会提前返回错误,而不会继续执行后续代码。
例如:
rust
fn process_number(num: Option<i32>) -> Option<i32> {
let doubled = num? * 2; // 如果 num 是 None,则提前返回 None
Some(doubled)
}
fn main() {
let result = process_number(Some(5));
println!("{:?}", result); // 输出:Some(10)
let result = process_number(None);
println!("{:?}", result); // 输出:None
}
范围运算符(..
)
范围运算符用于表示一个范围,常用于循环、切片等场景。Rust 提供了以下几种范围语法:
• a..b
:表示从a
到b
(不包含b
)的范围。
• a..=b
:表示从a
到b
(包含b
)的范围。
• ..b
:表示从 0 到b
(不包含b
)的范围。
• a..
:表示从a
到无穷大的范围。
例如:
rust
fn main() {
// 使用范围运算符进行循环
for i in 1..5 {
println!("{}", i); // 输出:1, 2, 3, 4
}
// 使用包含范围
for i in 1..=5 {
println!("{}", i); // 输出:1, 2, 3, 4, 5
}
// 使用范围切片
let numbers = [1, 2, 3, 4, 5];
let slice = &numbers[1..4];
println!("{:?}", slice); // 输出:[2, 3, 4]
}
路径运算符(::
)
路径运算符用于访问 Rust 中的命名空间、模块、结构体字段或关联函数。它有两种主要用途:
• 访问模块或命名空间:
rust
use std::collections::HashMap;
let mut map = HashMap::new();
• 访问关联函数或常量:
rust
let num = i32::MAX; // 访问 i32 类型的常量 MAX
println!("{}", num); // 输出:2147483647
解引用运算符(*
)
解引用运算符用于获取指针或智能指针指向的实际值。它常用于Box
、Rc
、RefCell
等智能指针类型。
例如:
rust
fn main() {
let num = 42;
// 创建一个对 num 的引用
let ref_num = #
// 使用解引用运算符获取引用指向的值
let deref_num = *ref_num;
println!("num: {}", num);
println!("ref_num: {:p}", ref_num); // 打印引用的内存地址
println!("deref_num: {}", deref_num);
//输出结果
//num: 42
//ref_num: 0x7ff6f832d358
//deref_num: 42
let boxed_value = Box::new(42);
let value = *boxed_value; // 解引用获取实际值
println!("{}", value); // 输出:42
}
在函数参数中使用解引用
当函数参数为引用类型时,可以在函数内部使用解引用运算符来访问引用所指向的值。
rust
fn print_value(ptr: &i32) {
// 解引用获取指向的值
let value = *ptr;
println!("The value is: {}", value);
}
fn main() {
let num = 100;
// 传递 num 的引用给函数
print_value(&num);
}
成员访问运算符(.
)
成员访问运算符用于访问结构体或枚举的字段,或调用方法。
例如:
rust
struct Person {
name: String,
age: u32,
}
fn main() {
let person = Person {
name: String::from("Alice"),
age: 30,
};
println!("Name: {}", person.name); // 访问字段
println!("Age: {}", person.age);
}