11月 09, 2023 LaGee
parse
parse被定義在str下面
用處為將一個字符串轉成其他類型
文件這樣寫到
pub fn parse<F>(&self) -> Result<F, <F as FromStr>::Err>
where
F: FromStr,
F為一個字串
回傳Result,如果Ok則包含解析字串的詞
否則回傳錯誤類型
而FromStr定義[2]則是
Trait std::str::FromStr
pub trait FromStr: Sized {
type Err;
// Required method
fn from_str(s: &str) -> Result<Self, Self::Err>;
}
透過接收字符串s
解析成類型Self,成功返回Ok否則Err
例子
舉一個簡單的例子
let num_str = "42";
let parsed: Result<i32, _> = num_str.parse();
match parsed {
Ok(parsed_num) => {
println!("Parsed number: {}", parsed_num);
},
Err(_) => {
println!("Parse error.");
}
}
Parsed number: 42
第一行為一個整數
第二行透過parse轉成i32,回傳一個result
第三行則是使用match分析result結果
如果是Ok,回傳數值42
如果為Err,顯示err
失敗的例子
let invalid_num_str = "abc";
let parsed: Result<i32, _> = invalid_num_str.parse();
match parsed {
Ok(parsed_num) => {
println!("Parsed number: {}", parsed_num);
}
Err(error) => {
println!("Parse error: {:?}", error);
}
}
Parse error: ParseIntError { kind: InvalidDigit }
第一行一個字串abc
第二行想將字串透過parse轉成i32
但因為是字串轉整數所以會報錯誤
因此match的結果顯示ParseIntError,類型為無效數值
parse常用在文字輸入、文件內容等
因不確定輸入類型是什麼
不能用類似
let invalid_num_str: &str
這種方式直接指定型態,容易發生panic
例如說有個程式會要求使用者輸入
println!("Enter your age: ");
let mut age_str = String::new();
io::stdin().read_line(&mut age_str).expect("Failed to read input");
let age: Result<u32, _> = age_str.trim().parse();
match age {
Ok(parsed_age) => println!("Your age is: {}", parsed_age),
Err(_) => println!("Invalid age input."),
}
Enter your age:
CCC
Invalid age input.
而使用者直接亂輸入一個年紀CCC
就可以透過match傳輸Err訊息
應用
舉一個比較困難的例子
假設要求使用者輸入多個數字,每個數字用逗點分開
並計算最大值、最小值以及和
use std::io;
fn main() {
let mut input = String::new();
println!("Enter a list of integers separated by commas:");
io::stdin().read_line(&mut input).expect("Failed to read input");
let numbers: Vec<i32> = input //String
.split(',') //Split<'_, char>
.map(|s| s.trim()) //impl Iterator<Item = &str>
.filter_map(|s| s.parse().ok()) //impl Iterator<Item = i32>
.collect();
if !numbers.is_empty() {
let sum: i32 = numbers.iter().sum();
let min: i32 = *numbers.iter().min().unwrap();
let max: i32 = *numbers.iter().max().unwrap();
println!("Sum: {}", sum);
println!("Minimum: {}", min);
println!("Maximum: {}", max);
} else {
println!("No valid integers entered.");
}
}
Enter a list of integers separated by commas:
3, 1, 5, 6, C, 13, ss, 88, ,6
Sum: 122
Minimum: 1
Maximum: 88使用者輸入後
透過分割split[3]、map[4]、filter_map[5]以及最後collect回傳一個數組
每個方法我都有把轉出來的型態打上去
可以看到map時候,型態為&str
而fliter_map裡面透過parse轉成i32
if以下則是判斷最大值以及最小值
這個檔案會放在GitHub[6],可以下載下來看
參考資料
[1] https://doc.rust-lang.org/std/primitive.str.html#method.parse
[2] https://doc.rust-lang.org/std/str/trait.FromStr.html
[3] https://lageeblog.blogspot.com/2023/11/rust-split.html
[4] https://lageeblog.blogspot.com/2023/10/rust-map.html
[5] https://lageeblog.blogspot.com/2023/11/rust-filtermap.html
[6] https://github.com/Lagee666/parse_practice
0 comments:
張貼留言