目标
掌握泛型、特征(Trait)、智能指针、并发和异步编程。
1. 泛型与特征(Trait)
泛型函数
ini
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
fn main() {
let numbers = vec![34, 50, 25, 100, 65];
println!("最大值: {}", largest(&numbers));
}
泛型结构体
ini
struct Point<T> {
x: T,
y: T,
}
fn main() {
let p1 = Point { x: 5, y: 10 };
let p2 = Point { x: 1.0, y: 4.0 };
}
Trait 定义与实现
rust
trait Summary {
fn summarize(&self) -> String;
}
struct NewsArticle {
headline: String,
author: String,
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{} by {}", self.headline, self.author)
}
}
fn main() {
let article = NewsArticle { headline: "Rust 进阶".to_string(), author: "Eric".to_string() };
println!("{}", article.summarize());
}
Trait bound 与 impl Trait
rust
fn notify(item: &impl Summary) {
println!("Breaking news! {}", item.summarize());
}
常用 Trait
Debug
:打印调试信息Clone
:深拷贝Copy
:轻量类型拷贝Drop
:自定义释放逻辑
2. 智能指针
Box:堆分配
css
let b = Box::new(5);
println!("b = {}", b);
Rc:引用计数
css
use std::rc::Rc;
let a = Rc::new(5);
let b = Rc::clone(&a);
println!("引用计数: {}", Rc::strong_count(&a));
Arc:线程安全引用计数
rust
use std::sync::Arc;
use std::thread;
let a = Arc::new(5);
let mut handles = vec![];
for _ in 0..3 {
let a = Arc::clone(&a);
let handle = thread::spawn(move || {
println!("{}", a);
});
handles.push(handle);
}
for h in handles {
h.join().unwrap();
}
RefCell:内部可变性
rust
use std::cell::RefCell;
let x = RefCell::new(5);
* x.borrow_mut() += 1;
println!("{}", x.borrow());
3. 并发编程
线程
rust
use std::thread;
let handle = thread::spawn(|| {
for i in 1..5 {
println!("子线程 {}", i);
}
});
for i in 1..5 {
println!("主线程 {}", i);
}
handle.join().unwrap();
Mutex 与 RwLock
ini
use std::sync::{Arc, Mutex};
use std::thread;
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter = Arc::clone(&counter);
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap();
*num += 1;
});
handles.push(handle);
}
for h in handles {
h.join().unwrap();
}
println!("结果: {}", *counter.lock().unwrap());
channels 消息传递
rust
use std::sync::mpsc;
use std::thread;
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
tx.send("Hello from thread").unwrap();
});
println!("{}", rx.recv().unwrap());
4. 异步编程
async / await
rust
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
println!("开始");
sleep(Duration::from_secs(2)).await;
println!("两秒后输出");
}
Future trait
rust
use std::future::Future;
async fn hello() {
println!("Hello async");
}
fn main() {
let f: impl Future<Output=()> = hello();
futures::executor::block_on(f);
}
tokio / async-std
- tokio:高性能异步运行时
- async-std:更接近标准库风格
- 异步 I/O、HTTP 请求、数据库访问
练习建议
- 多线程下载器
- 给定 URL 列表
- 每个 URL 用一个线程下载
- 保存到本地文件
- 异步网络爬虫
- 异步请求网页
- 并发抓取多个页面
- 提取信息并保存