为什么你可以在比赛中使用以前未声明的名字?

问题描述 投票:4回答:2

我在本书的第二章中遇到了解这个代码的问题:

let guess: u32 = match guess.trim().parse() {
    Ok(num) => num,
    Err(_) => continue,
};

我的问题是Ok(num) => numparse()返回一个值(OkErr),match将返回值与第一个臂进行比较。如果那些匹配,表达式将执行第一臂旁边的语句,对吧?

Ok(num)num似乎突然爆发,因为在之前的代码中没有声明num。与声明相同,=> numnum突然在范围内。所以

  1. 如果我猜对了,match将返回的值与Ok()匹配,然后将任何数字(在Ok内)分配给num。但为什么右边的num突然可用?
  2. 如果我猜对了,Ok(num)Ok(_)的区别是什么?
rust pattern-matching
2个回答
9
投票

如果我们从OkErr的来源开始,我们可能会有更好的主意。它们是Result枚举的一部分,定义如下:

enum Result<T, E> {
   Ok(T),
   Err(E),
}

TE是通用类型。 match本身就像C的switch声明,但更灵活。

match本身的一般形式是:

match value {
    pattern => expr,
    ...
}

如果那些匹配,表达式将执行第一臂旁边的语句,对吧?

但为什么右边的num突然可用?

因为match匹配每个手臂中=>左侧的图案。它可以解包元组,匹配struct字段,借用值的一部分等。

如果我猜对了,Ok(num)Ok(_)的区别是什么?

_是一个通配符模式,匹配一切。

Ok(num)Ok(_)之间的区别在于,在第一种情况下,您要求如果ResultOk变体,那么将其T类型的值存储在num中。在第二种情况下,你说你不关心Ok持有什么价值 - 只要Result是你要执行某些东西的Ok变种。

请记住,当您在模式中使用_时,您不能在代码中使用_,即这不起作用,因为_不是标识符:

let guess: u32 = match guess.trim().parse() {
    Ok(_) => _,
    Err(_) => continue,
};

0
投票

简短的回答。 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>

© www.soinside.com 2019 - 2024. All rights reserved.