Hi 大家,今天我們來看看 Rust 的迭代器系統。
fn main() {
let vec = vec![1, 2, 3, 4, 5];
// 三種迭代方式
// 1. iter() - 借用引用
for item in vec.iter() {
println!("借用: {}", item); // item 是 &i32
}
// 2. into_iter() - 取得所有權
let vec2 = vec![1, 2, 3];
for item in vec2.into_iter() {
println!("擁有: {}", item); // item 是 i32
}
// vec2 在這裡已經無法使用
// 3. iter_mut() - 可變借用
let mut vec3 = vec![1, 2, 3];
for item in vec3.iter_mut() {
*item *= 2; // 修改原始值
}
println!("修改後: {:?}", vec3);
}
fn main() {
let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 鏈式操作
let result: Vec<i32> = numbers
.iter()
.filter(|&&x| x % 2 == 0) // 過濾偶數
.map(|&x| x * x) // 平方
.filter(|&x| x > 10) // 大於 10
.collect(); // 收集結果
println!("處理結果: {:?}", result);
// 更複雜的操作
let text_numbers = numbers
.iter()
.take(5) // 取前 5 個
.skip(2) // 跳過前 2 個
.enumerate() // 加上索引
.map(|(i, &x)| format!("第{}個: {}", i, x))
.collect::<Vec<String>>();
for text in text_numbers {
println!("{}", text);
}
}
fn main() {
let numbers = vec![1, 2, 3, 4, 5];
// reduce 操作
let sum: i32 = numbers.iter().sum();
let product: i32 = numbers.iter().product();
println!("總和: {}", sum);
println!("乘積: {}", product);
// find 操作
let found = numbers.iter().find(|&&x| x > 3);
match found {
Some(value) => println!("找到大於 3 的數: {}", value),
None => println!("沒有找到"),
}
// any 和 all
let has_even = numbers.iter().any(|&x| x % 2 == 0);
let all_positive = numbers.iter().all(|&x| x > 0);
println!("有偶數: {}", has_even);
println!("全部正數: {}", all_positive);
// fold 和 reduce
let sum_fold = numbers.iter().fold(0, |acc, &x| acc + x);
let sum_reduce = numbers.iter().cloned().reduce(|acc, x| acc + x);
println!("fold 總和: {}", sum_fold);
println!("reduce 總和: {:?}", sum_reduce);
}
struct Counter {
current: usize,
max: usize,
}
impl Counter {
fn new(max: usize) -> Counter {
Counter { current: 0, max }
}
}
impl Iterator for Counter {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
if self.current < self.max {
let current = self.current;
self.current += 1;
Some(current)
} else {
None
}
}
}
fn main() {
let counter = Counter::new(5);
for num in counter {
println!("計數: {}", num);
}
// 使用自定義迭代器的適配器
let sum: usize = Counter::new(5)
.filter(|&x| x % 2 == 0)
.map(|x| x * x)
.sum();
println!("偶數平方和: {}", sum);
}
use std::io;
use std::collections::HashMap;
#[derive(Debug, Clone)]
struct LogEntry {
timestamp: String,
level: String,
message: String,
}
impl LogEntry {
fn new(line: &str) -> Option<LogEntry> {
let parts: Vec<&str> = line.splitn(3, ' ').collect();
if parts.len() == 3 {
Some(LogEntry {
timestamp: parts[0].to_string(),
level: parts[1].to_string(),
message: parts[2].to_string(),
})
} else {
None
}
}
}
fn main() {
println!("=== 日誌分析器 ===");
let sample_logs = vec![
"2024-01-01T10:00:00 INFO 系統啟動成功",
"2024-01-01T10:05:00 WARN 記憶體使用率較高",
"2024-01-01T10:10:00 ERROR 資料庫連線失敗",
"2024-01-01T10:15:00 INFO 使用者登入: user123",
"2024-01-01T10:20:00 ERROR 檔案讀取錯誤",
"2024-01-01T10:25:00 INFO 系統備份完成",
];
let logs: Vec<LogEntry> = sample_logs
.iter()
.filter_map(|&line| LogEntry::new(line))
.collect();
loop {
println!("\n選擇分析方式:");
println!("1. 依等級統計");
println!("2. 顯示錯誤日誌");
println!("3. 搜尋關鍵字");
println!("4. 離開");
match get_choice() {
1 => analyze_by_level(&logs),
2 => show_errors(&logs),
3 => search_logs(&logs),
4 => break,
_ => println!("無效選擇"),
}
}
}
fn get_choice() -> i32 {
let mut input = String::new();
io::stdin().read_line(&mut input).unwrap_or(0);
input.trim().parse().unwrap_or(0)
}
fn analyze_by_level(logs: &Vec<LogEntry>) {
let level_counts = logs
.iter()
.fold(HashMap::new(), |mut acc, log| {
*acc.entry(log.level.clone()).or_insert(0) += 1;
acc
});
println!("\n=== 等級統計 ===");
for (level, count) in level_counts {
println!("{}: {} 筆", level, count);
}
}
fn show_errors(logs: &Vec<LogEntry>) {
println!("\n=== 錯誤日誌 ===");
logs.iter()
.filter(|log| log.level == "ERROR")
.enumerate()
.for_each(|(i, log)| {
println!("{}. [{}] {}", i + 1, log.timestamp, log.message);
});
}
fn search_logs(logs: &Vec<LogEntry>) {
println!("請輸入搜尋關鍵字:");
let mut keyword = String::new();
io::stdin().read_line(&mut keyword).expect("讀取失敗");
let keyword = keyword.trim();
let matching_logs: Vec<&LogEntry> = logs
.iter()
.filter(|log| log.message.contains(keyword))
.collect();
println!("\n=== 搜尋結果: '{}' ===", keyword);
if matching_logs.is_empty() {
println!("未找到相關日誌");
} else {
for (i, log) in matching_logs.iter().enumerate() {
println!("{}. [{}] [{}] {}",
i + 1, log.timestamp, log.level, log.message);
}
}
}
今天我們掌握了: