我在本书的第二章中遇到了解这个代码的问题:
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};
我的问题是Ok(num) => num
:parse()
返回一个值(Ok
或Err
),match
将返回值与第一个臂进行比较。如果那些匹配,表达式将执行第一臂旁边的语句,对吧?
在Ok(num)
,num
似乎突然爆发,因为在之前的代码中没有声明num
。与声明相同,=> num
:num
突然在范围内。所以
match
将返回的值与Ok()
匹配,然后将任何数字(在Ok
内)分配给num
。但为什么右边的num
突然可用?Ok(num)
和Ok(_)
的区别是什么?如果我们从Ok
和Err
的来源开始,我们可能会有更好的主意。它们是Result
枚举的一部分,定义如下:
enum Result<T, E> {
Ok(T),
Err(E),
}
T
和E
是通用类型。 match
本身就像C的switch
声明,但更灵活。
match
本身的一般形式是:
match value {
pattern => expr,
...
}
如果那些匹配,表达式将执行第一臂旁边的语句,对吧?
是
但为什么右边的
num
突然可用?
因为match
匹配每个手臂中=>
左侧的图案。它可以解包元组,匹配struct字段,借用值的一部分等。
如果我猜对了,
Ok(num)
和Ok(_)
的区别是什么?
_
是一个通配符模式,匹配一切。
Ok(num)
和Ok(_)
之间的区别在于,在第一种情况下,您要求如果Result
是Ok
变体,那么将其T
类型的值存储在num
中。在第二种情况下,你说你不关心Ok
持有什么价值 - 只要Result
是你要执行某些东西的Ok
变种。
请记住,当您在模式中使用_
时,您不能在代码中使用_
,即这不起作用,因为_
不是标识符:
let guess: u32 = match guess.trim().parse() {
Ok(_) => _,
Err(_) => continue,
};
简短的回答。 patterns match
可以破坏结构,枚举...... see here
parse
的签名是pub fn parse<F>(&self) -> Result<F, <F as FromStr>::Err>
。其中有一个通用类型F
。
编译器找到let guess: u32 =
,它推断出你需要的是u32
。所以F
在这里是u32
。
然后模式匹配破坏从num
提取Ok<u32>