Rust 跨界:全面掌握跨平台应用开发
第一章:快速上手 Rust
1.2 基础语法与常用特性
1.2.1 数据类型与控制流
数据类型
Rust 提供了丰富的内置数据类型,主要分为标量类型和复合类型。
标量类型
标量类型表示单一的值,Rust 中的标量类型包括:
-
整数类型:Rust 提供了多种整数类型,分为有符号和无符号两类。它们的大小可以是 8、16、32、64 或 128 位。
- 有符号整数 :
i8
,i16
,i32
,i64
,i128
- 无符号整数 :
u8
,u16
,u32
,u64
,u128
- 默认类型 :如果没有指定,整数默认类型为
i32
。
示例代码:
rustlet a: i32 = -10; // 有符号整数 let b: u32 = 20; // 无符号整数
- 有符号整数 :
-
浮点数类型 :Rust 支持
f32
和f64
两种浮点数,分别表示 32 位和 64 位浮点数。浮点数使用f
后缀来指示类型。示例代码:
rustlet x: f32 = 3.14; // 32位浮点数 let y: f64 = 2.71828; // 64位浮点数
-
布尔类型 :布尔类型只有两个值:
true
和false
。示例代码:
rustlet is_active: bool = true;
-
字符类型:字符类型表示一个 Unicode 字符,使用单引号定义,支持多种语言的字符。
示例代码:
rustlet letter: char = 'A'; let emoji: char = '😊';
复合类型
复合类型用于将多个值组合在一起,主要有元组和数组。
-
元组:元组可以存储不同类型的值,使用小括号定义。元组的大小是固定的,定义后不可更改。
示例代码:
rustlet person: (&str, i32) = ("Alice", 30); // (名字, 年龄) let coordinates: (f64, f64) = (10.0, 20.0); // (x, y)
访问元组中的元素时,可以使用点语法:
rustlet (name, age) = person; println!("Name: {}, Age: {}", name, age);
-
数组:数组用于存储同一类型的多个值,使用方括号定义。数组的长度是固定的,定义后不可更改。
示例代码:
rustlet numbers: [i32; 5] = [1, 2, 3, 4, 5]; // 长度为5的整数数组 let first = numbers[0]; // 访问数组元素
Rust 还支持使用
vec!
宏创建动态数组(向量):rustlet mut dynamic_numbers = vec![1, 2, 3]; dynamic_numbers.push(4); // 添加新元素
控制流
Rust 提供了多种控制流结构,包括条件语句、循环等。
条件语句
使用 if
和 else
进行条件判断,Rust 支持多种条件语句结构。
-
基本
if
语句示例代码:
rustlet score = 85; if score >= 90 { println!("Grade: A"); } else if score >= 80 { println!("Grade: B"); } else { println!("Grade: C"); }
-
条件表达式
Rust 的
if
语句可以作为表达式,返回值。示例代码:
rustlet max = if a > b { a } else { b };
-
模式匹配
使用
match
语句进行复杂的条件判断和模式匹配。示例代码:
rustmatch score { 90..=100 => println!("Grade: A"), 80..=89 => println!("Grade: B"), _ => println!("Grade: C"), }
循环
Rust 提供了 loop
、while
和 for
三种循环结构。
-
无限循环
使用
loop
关键字创建无限循环,通常配合break
使用。示例代码:
rustlet mut count = 0; loop { count += 1; if count > 5 { break; // 结束循环 } println!("Count: {}", count); }
-
while
循环while
循环在条件为真时执行。示例代码:
rustlet mut count = 0; while count < 5 { println!("Count: {}", count); count += 1; }
-
for
循环for
循环用于遍历集合(如数组、切片、范围等)。示例代码:
rustlet array = [1, 2, 3, 4, 5]; for number in array.iter() { println!("Number: {}", number); } // 使用范围 for i in 1..=5 { println!("Count: {}", i); }
1.2.2 函数与模块
函数
Rust 的函数定义非常灵活,支持参数、返回值、可变参数等。
定义函数
函数使用 fn
关键字定义,支持参数类型和返回值类型。
示例代码:
rust
fn add(a: i32, b: i32) -> i32 {
a + b
}
调用函数
调用函数时,传入参数并获取返回值。
示例代码:
rust
let result = add(2, 3);
println!("Result: {}", result);
可变参数函数
Rust 支持可变参数函数,可以使用切片作为参数类型。
示例代码:
rust
fn print_numbers(numbers: &[i32]) {
for &number in numbers.iter() {
println!("{}", number);
}
}
匿名函数
Rust 还支持匿名函数(闭包),可以作为参数传递。
示例代码:
rust
let add = |a: i32, b: i32| a + b;
let result = add(5, 10);
println!("Result: {}", result);
模块与包
Rust 使用模块系统来组织代码。模块是一个代码的集合,可以将相关的功能分组在一起。
定义模块
使用 mod
关键字定义模块。
示例代码:
rust
mod math {
pub fn multiply(a: i32, b: i32) -> i32 {
a * b
}
}
// 在其他地方调用模块中的函数
let product = math::multiply(4, 5);
println!("Product: {}", product);
模块中的子模块
模块可以包含其他子模块,使用 {}
包围子模块。
示例代码:
rust
mod outer {
pub mod inner {
pub fn inner_function() {
println!("This is an inner function.");
}
}
}
outer::inner::inner_function();
包的概念
包是 Rust 项目的基本构建块,包含多个模块和库。通过 Cargo.toml
文件管理包的依赖和配置。
1.2.3 错误处理
Rust 提供了强大的错误处理机制,主要通过 Result
和 Option
类型实现。
使用 Result
类型
Result
是一个枚举,表示操作的成功或失败。它有两个变体:Ok
和 Err
。
示例代码:
rust
fn divide(a: f64, b: f64) -> Result<f64, String> {
if b == 0.0 {
Err(String::from("Cannot divide by zero"))
} else {
Ok(a / b)
}
}
// 调用函数并处理结果
match divide(10.0, 2.0) {
Ok(result) => println!("Result: {}", result),
Err(e) => println!("Error: {}", e),
}
使用 Option
类型
Option
用于表示可能存在或不存在的值,包含两个变体:Some
和 None
。
示例代码:
rust
fn find_item(index: usize) -> Option<&'static str> {
let items = ["Apple", "Banana", "Cherry"];
if index < items.len() {
Some(items[index])
} else {
None
}
}
// 调用函数并处理结果
match find_item(1) {
Some(item) => println!("Found: {}", item),
None => println!("Item not found"),
}
1.2.4 泛型与特征
泛型允许我们在函数和数据结构中使用占位符类型,使代码更加灵活。
定义泛型函数
示例代码:
rust
fn print_item<T: std::fmt::Display>(item: T) {
println!("Item: {}", item);
}
使用特征
特征定义了一组方法,可以被不同类型实现。
示例代码:
rust
trait Describe {
fn describe(&self) -> String;
}
struct Dog;
impl Describe for Dog {
fn describe(&self) -> String {
String::from("This is a dog.")
}
}
let dog = Dog;
println!("Dog: {}", dog.describe());
特征约束
特征约束用于限制泛型类型的行为。
示例代码:
rust
fn print_and_describe<T: Describe>(item: T) {
println!("Description: {}", item.describe());
}
1.2.5 宏的使用
Rust 支持宏,可以用来简化代码。
定义宏
使用 macro_rules!
定义宏。
示例代码:
rust
macro_rules! say_hello {
() => {
println!("Hello, Macro!");
};
}
fn main() {
say_hello!(); // 调用宏
}
带参数的宏
可以定义带参数的宏来处理更复杂的逻辑。
示例代码:
rust
macro_rules! create_function {
($func_name:ident) => {
fn $func_name() {
println!("Function {:?} created!", stringify!($func_name));
}
};
}
create_function!(foo); // 创建函数 foo
fn main() {
foo(); // 调用 foo 函数
}
使用宏生成代码
宏可以动态生成代码,以减少重复代码。
示例代码:
rust
macro_rules! generate_struct {
($name:ident) => {
struct $name {
value: i32,
}
};
}
generate_struct!(MyStruct); // 生成结构体 MyStruct
fn main() {
let instance = MyStruct { value: 10 };
println!("Value: {}", instance.value);
}
小结
本节详细介绍了 Rust 的基本语法和常用特性,包括数据类型、控制流、函数、模块、错误处理、泛型、特征和宏的使用。通过丰富的示例代码,您可以更深入地理解这些特性在实际开发中的应用。