为什么学习Rust?
先前构造webview应用时使用electron有运行慢、占用高的难点,而Tauri作为另一款实现webview的框架具有轻量(使用系统自带webview2)、高效(Rust作为后端语言)的优点,因而将项目转移到了Tauri,Rust成为了学习的一部分。
参考教程:https://www.runoob.com/rust/rust-tutorial.html
1. Hello World
fn main() {
println!("Hello, Rust!");
println!("Alice is watching you learn...");
}
编译运行:
rustc main.rs
./main # Windows: main.exe
2. 变量与可变性
Rust是静态类型语言,但支持类型推断。
let a = 1; // 默认不可变
let mut b = 2; // 可变变量
let c: i32 = 3; // 显式指定类型
// 重新绑定(shadowing)
let x = 5;
let x = x + 1; // ✅ 允许,创建新变量
// x = x + 1; // ❌ 错误,x不可变
// 常量
const MAX_POINTS: u32 = 100_000;
注意:不可变变量与常量的区别:
- 常量必须指定类型,值在编译时确定
- 可以对不可变变量重新绑定(shadowing)
3. 数据类型
标量类型(Scalar Types)
i8,i16,i32,i64,i128,isize- 有符号整数u8,u16,u32,u64,u128,usize- 无符号整数f32,f64- 浮点数bool- 布尔值(true/false)char- Unicode标量值(4字节)
复合类型(Compound Types)
元组(Tuple)
let tup: (i32, f64, char) = (500, 6.4, 'A');
let (x, y, z) = tup; // 解构
println!("{}", tup.0); // 通过索引访问
数组(Array)
let arr = [1, 2, 3, 4, 5]; // 类型相同,长度固定
let a: [i32; 5] = [1, 2, 3, 4, 5];
let b = [3; 5]; // [3, 3, 3, 3, 3]
4. 控制流
if 表达式
let number = 6;
if number % 2 == 0 {
println!("偶数");
} else {
println!("奇数");
}
// if 作为表达式(必须返回相同类型)
let result = if condition { 5 } else { 6 };
循环
// loop - 无限循环
let mut count = 0;
loop {
count += 1;
if count == 3 { break; }
}
// while - 条件循环
while number != 0 {
number -= 1;
}
// for - 遍历集合
for element in arr.iter() {
println!("{}", element);
}
for number in 1..4 { // 1, 2, 3
println!("{}", number);
}
match 表达式(模式匹配)
match value {
1 => println!("一"),
2 | 3 | 5 | 7 | 11 => println!("质数"),
13..=19 => println!("13到19之间"),
_ => println!("其他"),
}
5. 函数
// 定义函数
fn add(x: i32, y: i32) -> i32 {
x + y // 没有分号,这是表达式
}
// 返回多个值(使用元组)
fn calculate(x: i32, y: i32) -> (i32, i32) {
(x + y, x - y)
}
// 语句 vs 表达式
let y = {
let x = 3;
x + 1 // 表达式块返回值
};
6. 所有权(Ownership) - Rust核心特性
所有权规则
- 每个值都有一个所有者
- 一次只能有一个所有者
- 当所有者离开作用域时,值将被丢弃
移动(Move)
let s1 = String::from("hello");
let s2 = s1; // 所有权从s1移动到s2
// println!("{}", s1); // ❌ 错误!s1不再有效
克隆(Clone)
let s1 = String::from("hello");
let s2 = s1.clone(); // 深拷贝
println!("{} {}", s1, s2); // ✅ 正确
引用与借用(References & Borrowing)
let s1 = String::from("hello");
let len = calculate_length(&s1); // &创建引用(借用)
println!("{} {}", s1, len); // ✅ s1仍然有效
// 不可变引用(可以有多个)
let r1 = &s;
let r2 = &s;
// 可变引用(只能有一个)
let mut s = String::from("hello");
let r = &mut s;
// let r2 = &mut s; // ❌ 错误!不能有多个可变引用
切片(Slices)
let s = String::from("hello world");
let hello = &s[0..5]; // "hello"
let world = &s[6..11]; // "world"
let whole = &s[..]; // 整个字符串
// &str vs &String
let s_ref: &String = &s; // 对String的引用
let str_slice: &str = &s[..]; // 字符串切片
// &s 可以自动解引用为 &str
7. 结构体(Structs)
定义和使用
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
// 创建实例
let user1 = User {
email: String::from("user@example.com"),
username: String::from("username"),
active: true,
sign_in_count: 1,
};
// 结构体更新语法
let user2 = User {
email: String::from("user2@example.com"),
..user1 // 其余字段使用user1的值
};
元组结构体
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
let black = Color(0, 0, 0);
println!("R:{}, G:{}, B:{}", black.0, black.1, black.2);
方法
impl Rectangle {
// 关联函数(类似静态方法)
fn square(size: u32) -> Rectangle {
Rectangle { width: size, height: size }
}
// 方法
fn area(&self) -> u32 {
self.width * self.height
}
// 修改方法
fn double(&mut self) {
self.width *= 2;
self.height *= 2;
}
}
let rect = Rectangle { width: 30, height: 50 };
println!("面积: {}", rect.area());
let square = Rectangle::square(10);
8. 枚举(Enums)和模式匹配
定义枚举
enum IpAddrKind {
V4,
V6,
}
enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
Option 枚举
enum Option<T> {
Some(T),
None,
}
let some_number = Some(5);
let absent_number: Option<i32> = None;
match 表达式
match coin {
Coin::Penny => {
println!("幸运硬币!");
1
},
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter(state) => {
println!("来自{:?}州的25分硬币", state);
25
},
}
if let 简洁控制流
if let Some(3) = some_value {
println!("值是3");
}
9. 模块系统
创建模块
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
// 使用模块
use crate::front_of_house::hosting;
hosting::add_to_waitlist();
可见性
pub:公共可见- 默认私有(模块内可见)
10. 常见集合
Vector
let v: Vec<i32> = Vec::new();
let v = vec![1, 2, 3];
v.push(4);
let third: &i32 = &v[2];
let third: Option<&i32> = v.get(2);
String
let mut s = String::new();
let s = "初始内容".to_string();
let s = String::from("初始内容");
s.push_str("追加内容");
s.push('!');
HashMap
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
let team_name = String::from("Blue");
let score = scores.get(&team_name);
11. 错误处理
panic! 宏
panic!("严重错误!");
Result 枚举
enum Result<T, E> {
Ok(T),
Err(E),
}
let f = File::open("hello.txt");
let f = match f {
Ok(file) => file,
Err(error) => panic!("打开文件失败: {:?}", error),
};
// 使用 ? 运算符
let f = File::open("hello.txt")?;
12. 泛型
泛型函数
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
泛型结构体
struct Point<T> {
x: T,
y: T,
}
impl<T> Point<T> {
fn x(&self) -> &T {
&self.x
}
}
13. Trait(特征)
定义和实现Trait
pub trait Summary {
fn summarize(&self) -> String;
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{} by {}", self.headline, self.author)
}
}
Trait作为参数
pub fn notify(item: &impl Summary) {
println!("新闻摘要: {}", item.summarize());
}
// Trait Bound语法
pub fn notify<T: Summary>(item: &T) {
println!("新闻摘要: {}", item.summarize());
}
14. 生命周期
生命周期注解
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
结构体中的生命周期
struct ImportantExcerpt<'a> {
part: &'a str,
}
impl<'a> ImportantExcerpt<'a> {
fn level(&self) -> i32 {
3
}
}
关键概念总结
- 所有权系统:Rust内存安全的核心
- 借用检查器:编译时确保引用安全
- 零成本抽象:高级特性不带来运行时开销
- 模式匹配:强大的控制流工具
- Trait系统:Rust的多态机制
- 生命周期:确保引用有效性
此方悬停