我是Rust的新手,刚刚遇到了一个很好的if-let结构。我有两个值a和b,它们都是Option。我使用if-let如下:
if-let
a
b
Option
if let (Some(a), Some(b)) = (a, b) { println!("You passed in {:?}, {:?}"); }
这是可行的,但我不明白为什么我需要 Package 我的值,如Some(a),这已经是一个Option。Option不是已经是Some或None中的一个吗?
Some(a)
Some
None
wfypjpf41#
这是在rust中使用 * 模式匹配 * 的地方之一。
let x: Option<i32> = Some(42); if let Some(x) = x { println!("{}", x); }
Rust知道x是Option类型,而这是一个枚举,有两种可能的变体。因此,这个模式匹配表示的是查看x,并将其与Some(x)进行比较。如果x是None,则匹配将失败(因为None和Some(_)是不同的变量)。但是如果x是Some,则模式将匹配**,并且Some中的值将被赋给变量x**。这将依次 * 遮蔽 * 前一个变量x,并且仅在此if let范围内有效你所做的实际上是相同的,只是你匹配作为一个模式元组的两个选项。阅读这本书的chapter模式匹配更好地理解它,并看到所有其他地方,你可以找到它在生 rust 。
x
Some(x)
Some(_)
if let
a9wyjsp72#
这里需要注意的是,你没有 Package 你的值。当你使用if let Some(x) = y {时,你是在测试变量y是否匹配模式Some(x),如果匹配,就绑定x的值,使其成为选项 Package 的内容。你可以在here一书中阅读模式匹配在你的例子中,你在两边都使用了a和b,这有点误导人。你用新的变量遮蔽了原来的变量。你可以写if let (Some(x), Some(y)) = (a, b) {,它也可以工作,但是a和b仍然是选项,x和y可以作为先前 Package 的值。另外,print语句需要传入a和b。假定原始代码中确实有这两个参数。
if let Some(x) = y {
y
if let (Some(x), Some(y)) = (a, b) {
woobm2wo3#
您正在将“maybe-Some“的内容解包到它所保存的值,并且只有当两者都是Some时才进入该块。(而不是仅仅复制),并且在None时根本不运行?您的代码正在执行有意义的工作,测试Some ness,并使用原始Some对象的内容解包(和隐藏)原始a和b。如果没有Some,Rust就无法自行推断测试和解包。
jjhzyzn04#
首先,让我们暂时忘记元组,它只是这个问题的噪音。您不需要 Package 它们,您可以执行以下操作:
if let a = a { println!("{:?}", a); }
但是if的意义何在呢?在Rust中,这样的赋值从来不会失败!实际上,当你编写一个let LEFT = RIGHT;时,LEFT部分在技术上被称为 binding,这是一种将名称(变量)* 绑定 * 到值的特殊语法。一般来说,绑定可能会出错,如果您键入let Some(inner_a) = a;,则如果a是Some(42),则inner_a将绑定到42;但是如果a是无, the variable inner_a '将是未赋值的,这是不好的。解决这个问题的通常方法是使用一个匹配,它尝试多个绑定,直到一个成功:
if
let LEFT = RIGHT;
LEFT
let Some(inner_a) = a;
Some(42)
inner_a
42
, the variable
let inner_a = match a { Some(x) => x, None => 0, };
if let结构只是一个匹配的语法糖:
if let Some(inner_a) = a { do_something(inner_a); }
被脱糖为:
match a { Some(inner_a) => { do_something(inner_a); } _ => {} //catch-all binding }
TL;DR;=左边的Some()不是在 * Package * 值,而是在 * 展开 * 它!
=
Some()
4条答案
按热度按时间wfypjpf41#
这是在rust中使用 * 模式匹配 * 的地方之一。
Rust知道
x
是Option
类型,而这是一个枚举,有两种可能的变体。因此,这个模式匹配表示的是查看x
,并将其与Some(x)
进行比较。如果x
是None
,则匹配将失败(因为None
和Some(_)
是不同的变量)。但是如果x
是Some
,则模式将匹配**,并且Some
中的值将被赋给变量x
**。这将依次 * 遮蔽 * 前一个变量x
,并且仅在此if let
范围内有效你所做的实际上是相同的,只是你匹配作为一个模式元组的两个选项。阅读这本书的chapter模式匹配更好地理解它,并看到所有其他地方,你可以找到它在生 rust 。
a9wyjsp72#
这里需要注意的是,你没有 Package 你的值。当你使用
if let Some(x) = y {
时,你是在测试变量y
是否匹配模式Some(x)
,如果匹配,就绑定x
的值,使其成为选项 Package 的内容。你可以在here一书中阅读模式匹配在你的例子中,你在两边都使用了
a
和b
,这有点误导人。你用新的变量遮蔽了原来的变量。你可以写if let (Some(x), Some(y)) = (a, b) {
,它也可以工作,但是a
和b
仍然是选项,x
和y
可以作为先前 Package 的值。另外,print语句需要传入
a
和b
。假定原始代码中确实有这两个参数。woobm2wo3#
您正在将“maybe-
Some
“的内容解包到它所保存的值,并且只有当两者都是Some
时才进入该块。(而不是仅仅复制),并且在None
时根本不运行?您的代码正在执行有意义的工作,测试Some
ness,并使用原始Some
对象的内容解包(和隐藏)原始a
和b
。如果没有Some
,Rust就无法自行推断测试和解包。jjhzyzn04#
首先,让我们暂时忘记元组,它只是这个问题的噪音。
您不需要 Package 它们,您可以执行以下操作:
但是
if
的意义何在呢?在Rust中,这样的赋值从来不会失败!实际上,当你编写一个
let LEFT = RIGHT;
时,LEFT
部分在技术上被称为 binding,这是一种将名称(变量)* 绑定 * 到值的特殊语法。一般来说,绑定可能会出错,如果您键入
let Some(inner_a) = a;
,则如果a
是Some(42)
,则inner_a
将绑定到42
;但是如果a
是无, the variable
inner_a '将是未赋值的,这是不好的。解决这个问题的通常方法是使用一个匹配,它尝试多个绑定,直到一个成功:
if let
结构只是一个匹配的语法糖:被脱糖为:
TL;DR;
=
左边的Some()
不是在 * Package * 值,而是在 * 展开 * 它!