也有英文版文章
Also this tutorial has been written in English
Check out my Medium
Result<T, E>
是用來回傳&傳播錯誤(Propagate)的型別
enum Result<T, E> {
Ok(T),
Err(E),
}
請注意get_choice(input: &str)函式。
#[derive(Debug)]
enum MenuChoice {
MainMenu,
Start,
Quit,
}
fn get_choice(input: &str) -> Result<MenuChoice, String> {
match input {
"mainmenu" => Ok(MenuChoice::MainMenu),
"start" => Ok(MenuChoice::Start),
"quit" => Ok(MenuChoice::Quit),
_ => Err("menu choice not found".to_owned()),
}
}
fn print_choice(choice: &MenuChoice) {
println!("choice = {:?}", choice);
}
fn main() {
let choice: Result<MenuChoice, _> = get_choice("mainmenu");
match choice {
Ok(inner_choice) => print_choice(&inner_choice),
Err(e) => println!("error = {:?}", e),
}
}
/*
choice = MainMenu
*/
What if I set it to something not in the enum MenuChoice
如果設成不在enum MenuChoice裡的東西...
let choice: Result<MenuChoice, _> = get_choice("leave");
match choice {
Ok(inner_choice) => print_choice(&inner_choice),
Err(e) => println!("error = {:?}", e),
}
/*
error = "menu choice not found"
*/
fn pick_choice(input: &str) -> Result<(), String> {
let choice: MenuChoice = get_choice(input)?;
print_choice(&choice);
Ok(()) /* everyhting is fine */
}
fn main() {
let choice = pick_choice("start");
println!("choice value = {:?}", choice);
}
/*
choice = Start
choice value = Ok(())
*/
試試看一些例外(exception)
fn pick_choice(input: &str) -> Result<(), String> {
let choice: MenuChoice = get_choice(input)?;
print_choice(&choice);
Ok(()) /* everyhting is fine */
}
fn main() {
let choice = pick_choice("something");
println!("choice value = {:?}", choice);
}
/*
choice value = Err("menu choice not found")
*/
#[derive(Debug)]
enum MenuChoice {
MainMenu,
Start,
Quit,
}
fn get_choice(input: &str) -> Result<MenuChoice, String> {
match input {
"mainmenu" => Ok(MenuChoice::MainMenu),
"start" => Ok(MenuChoice::Start),
"quit" => Ok(MenuChoice::Quit),
_ => Err("menu choice not found".to_owned()),
}
}
fn print_choice(choice: &MenuChoice) {
println!("choice = {:?}", choice);
}
fn pick_choice(input: &str) -> Result<(), String> {
let choice: MenuChoice = get_choice(input)?;
print_choice(&choice);
Ok(()) /* everyhting is fine */
}
fn main() {
let choice = pick_choice("something");
println!("choice value = {:?}", choice);
}
#[derive(Debug)]
struct Adult {
age: u8,
name: String,
}
impl Adult {
fn new(age: u8, name: &str) -> Result<Self, &str> {
if age >= 21 {
Ok(Self {
age,
name: name.to_owned(),
})
} else {
Err("Age must be at least 21")
}
}
}
fn main() {
let child = Adult::new(15, "Alice");
let adult = Adult::new(34, "Bob");
match child {
Ok(child) => println!("{} is {} years old.", child.name, child.age),
Err(e) => println!("{e}"),
}
match adult {
Ok(adult) => println!("{} is {} years old.", adult.name, adult.age),
Err(e) => println!("{e}"),
}
}
/*
Age must be at least 21
Bob is 34 years old.
*/