rust 项目管理 + 常见集合 + 错误处理 + 泛型与 trait
一、Packages、Crate、Modules
实操代码如下,便于后期学习:
front_of_house.rs:
pub mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
fn seat_at_table() {}
}
mod serving {
fn take_order() {}
fn server_order() {}
fn take_payment() {}
}
}
lib.rs:
//#[cfg(test)]
mod front_of_house;
pub use crate::front_of_house::front_of_house::hosting;
// pub fn eat_at_restaurant() {
// hosting::add_to_waitlist();
// hosting::add_to_waitlist();
// hosting::add_to_waitlist();
// }
// use front_of_house::hosting;
pub fn eat_at_restaurant() {
// Absolute path
crate::front_of_house::front_of_house::hosting::add_to_waitlist();
// Relative path
front_of_house::front_of_house::hosting::add_to_waitlist();
// Order a breakfast in the summer with Rye toast
let mut meal = back_of_house::Breakfast::summer("Rye");
// Change our mind about what bread we'd like
meal.toast = String::from("Wheat");
println!("I'd like {} toast please", meal.toast);
// The next line won't compile if we uncomment it; we're not allowed
// to see or modify the seasonal fruit that comes with the meal
// meal.seasonal_fruit = String::from("blueberries");
}
fn serve_order() {}
mod back_of_house {
pub struct Breakfast {
pub toast: String,
seasonal_fruit: String,
}
impl Breakfast {
pub fn summer(toast: &str) -> Breakfast {
Breakfast {
toast: String::from(toast),
seasonal_fruit: String::from("peaches"),
}
}
}
}
二、collections
use std::collections::HashMap;
fn main() {
let mut s: Vec<i32> = Vec::new();
// new 需要指定类型
s.push(5);
println!("{:?}", s);
s.push(6);
s.push(7);
s.push(8);
println!("{:?}", s);
let v = vec![1, 2, 3, 4, 5];
let third: &i32 = &v[2];
println!("The third element is {}", third);
match v.get(2) {
Some(third) => println!("The third element is {}", third),
None => println!("There is no third element."),
}
let v = vec![1, 2, 3, 4, 5];
// let does_not_exist = &v[100];
// let does_not_exist = v.get(100);
let mut v = vec![1, 2, 3, 4, 5];
let first = &v[0];
// 不可 v.push(6)
// 不能在不可变引用后添加
println!("The first element is: {}", first);
// 遍历
let v = vec![100, 32, 57];
for i in &v {
println!("{}", i);
}
// *解引用运算符
let mut v = vec![100, 32, 57];
for i in &mut v {
*i += 50;
println!("{}", i);
}
// 用枚举存储不同值,再套进vector
enum SpreadsheetCell {
Int(i32),
Float(f64),
Text(String),
}
let row = vec![
SpreadsheetCell::Int(3),
SpreadsheetCell::Text(String::from("blue")),
SpreadsheetCell::Float(10.12),
];
// hash map
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
println!("{:?}", scores);
let team_name = String::from("Blue");
let score = scores.get(&team_name);
println!("Blue socre is {:?}", score);
for (key, value) in &scores {
println!("{}: {}", key, value);
}
scores.entry(String::from("Yellow")).or_insert(50);
scores.entry(String::from("Blue")).or_insert(50);
// 使用 collect 方法将这个元组 vector 转换成一个 HashMap
let teams = vec![String::from("Blue"), String::from("Yellow")];
let initial_scores = vec![10, 50];
let scores: HashMap<_, _> = teams.iter().zip(initial_scores.iter()).collect();
let field_name = String::from("Favorite color");
let field_value = String::from("Blue");
let mut map = HashMap::new();
map.insert(field_name, field_value);
// 这里 field_name 和 field_value 不再有效,
// 尝试使用它们看看会出现什么编译错误!
let text = "hello world wonderful world";
let mut map = HashMap::new();
for word in text.split_whitespace() {
let count = map.entry(word).or_insert(0);
*count += 1;
println!("{} {}", word,count);
}
println!("{:?}", map);
}
三、panic
use std::fs::File;
use std::io::ErrorKind;
use std::io;
use std::io::Read;
fn main() {
let f = File::open("hello.txt");
// let f = File::open("hello.txt").unwrap();
// let f = File::open("hello.txt").expect("Failed to open hello.txt");
let f = match f {
Ok(file) => file,
Err(error) => match error.kind() {
ErrorKind::NotFound => match File::create("hello.txt") {
Ok(fc) => fc,
Err(e) => panic!("Problem creating the file: {:?}", e),
},
other_error => panic!("Problem opening the file: {:?}", other_error),
},
};
}
fn read_username_from_file() -> Result<String, io::Error> {
let mut f = File::open("hello.txt")?;
let mut s = String::new();
f.read_to_string(&mut s)?;
Ok(s)
}
// 使用闭包
// fn main() {
// let f = File::open("hello.txt").unwrap_or_else(|error| {
// if error.kind() == ErrorKind::NotFound {
// File::create("hello.txt").unwrap_or_else(|error| {
// panic!("Problem creating the file: {:?}", error);
// })
// } else {
// panic!("Problem opening the file: {:?}", error);
// }
// });
// }
四、generics、trait
// 在函数定义中使用泛型
// fn largest<T>(list: &[T]) -> T {
// let mut largest = list[0];
// for &item in list.iter() {
// if item > largest {
// largest = item;
// }
// }
// largest
// }
// 在结构体中使用泛型
struct Point<T, U> {
x: T,
y: U,
}
// 枚举定义中的泛型
enum Result<T, E> {
Ok(T),
Err(E),
}
// 定义 trait
pub trait Summary {
fn summarize(&self) -> String {
String::from("(Read more...)")
}
}
pub struct NewsArticle {
pub headline: String,
pub location: String,
pub author: String,
pub content: String,
}
impl Summary for NewsArticle {
// fn summarize(&self) -> String {
// format!("{}, by {} ({})", self.headline, self.author, self.location)
// }
}
fn main() {
// let number_list = vec![34, 50, 25, 100, 65];
// let result = largest(&number_list);
// println!("The largest number is {}", result);
// let char_list = vec!['y', 'm', 'a', 'q'];
// let result = largest(&char_list);
// println!("The largest char is {}", result);
let both_integer = Point { x: 5, y: 10 };
let both_float = Point { x: 1.0, y: 4.0 };
let integer_and_float = Point { x: 5, y: 4.0 };
let article = NewsArticle {
headline: String::from("Penguins win the Stanley Cup Championship!"),
location: String::from("Pittsburgh, PA, USA"),
author: String::from("Iceburgh"),
content: String::from("The Pittsburgh Penguins once again are the best
hockey team in the NHL."),
};
println!("New article available! {}", article.summarize());
}
五、BUG 总结
- error[E0433]: failed to resolve: maybe a missing crate
front_of_house
?
error[E0433]: failed to resolve: use of undeclared crate or modulefront_of_house
解决:注释掉#[cfg(test)] - error[E0432]: unresolved import
crate::front_of_house::hosting
解决:crate后跟文件名继续::跟mod名::函数名