事件:继续完成rustlings和代码改写。
fn read_and_validate(b: &mut dyn io::BufRead) -> Result<PositiveNonzeroInteger, Box<dyn error::Error>> {
let mut line = String::new();
b.read_line(&mut line)?;
let num: i64 = line.trim().parse()?;
let answer = PositiveNonzeroInteger::new(num)?;
Ok(answer)
}
这个代码蕴含了比较丰富的信息,首先,Result类型的数据后面加?等效于一个match语句:若为Ok(T)类,则返回括号内value(注意不是Ok(value))。否则,则函数返回Err(V)。其次,用
Box 可以表示各种类型的Err。
let mut optional_values_vec: Vec<Option<i8>> = Vec::new();
for x in 1..10 {
optional_values_vec.push(Some(x));
}
while let Some(Some(value)) = optional_values_vec.pop() {
println!("current value: {}", value);
Vec::pop()返回的是option类型,所以需要两个Some来获取i8类型。
pub enum DivisionError {
NotDivisible(NotDivisibleError),
DivideByZero,
}
pub struct NotDivisibleError {
dividend: i32,
divisor: i32,
}
pub fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {
if b==0{
Err(DivisionError::DivideByZero)
}
else if a%b==0{
Ok(a/b)
}
else{
Err(DivisionError::NotDivisible(NotDivisibleError{dividend:a , divisor:b})) //卡壳处
}
}
此处卡的时间挺久的,究其原因还是对enum的用法不是特别熟练。
我最开始给出的答案是:
Err(DivisionError::NotDivisibleError{dividend:a , divisor:b})
这里就混淆了枚举本身种类和枚举种类的value,这里,NotDivisibleError的种类中包含NotDivisible,而该种类的value类型为struct NotDivisible,这样分析清楚前因后果才能快速写出正确的代码。
fn test_iterate_into_string() {
let words = vec!["hello", " ", "world"];
let capitalized_words = words.iter().map(|x| capitalize_first(x)).collect::<Vec<_>>().join("");
assert_eq!(capitalized_words, "Hello World");
}
这里是另一处卡壳代码,对Vec中所有元素进行操作需要借助迭代器的map(),返回值同样为迭代器,通过collect()方法重新组织为向量。