Rust Can&;vec.iter(){..}编译中的一些(u)?
我尝试运行以下代码段:Rust Can&;vec.iter(){..}编译中的一些(u)?,rust,Rust,我尝试运行以下代码段: let a = &[Some(1), Some(2), Some(3), None, Some(4)]; let mut sum = 0; for &Some(x) in a.iter() { sum += x; } assert_eq!(sum, 1+2+3+4); 编译器回答说: about_loops.rs:39:9: 43:18 error: non-exhaustive patterns: None not covered abou
let a = &[Some(1), Some(2), Some(3), None, Some(4)];
let mut sum = 0;
for &Some(x) in a.iter() {
sum += x;
}
assert_eq!(sum, 1+2+3+4);
编译器回答说:
about_loops.rs:39:9: 43:18 error: non-exhaustive patterns: None not covered
about_loops.rs:39 for &Some(x) in a.iter() {
about_loops.rs:40 sum += x;
about_loops.rs:41 }
about_loops.rs:42
about_loops.rs:43 assert_eq!(sum, 1+2+3+4);
error: aborting due to previous error
make: *** [all] Error 101
我能在不使用luke和hobbs建议的匹配表达式的情况下为for循环编译这样的构造吗?或者这个错误消息是否具有误导性?
从for的语法定义来看,似乎并非如此
for_expr : "for" pat "in" expr '{' block '}' ;
我在:
rustc 0.11.0-pre-nightly (6291955 2014-05-19 23:41:20 -0700)
host: x86_64-apple-darwin
澄清:for_expr的“pat”部分表达能力如何?与下的定义不同,中未指定此项。
某些
是枚举中的一种类型。选项有两种类型,Some(T)
和None
。您的代码假定a.iter()
始终是Some(T)
,并且从不检查None
。要添加检查,可以使用匹配项
。大概是这样的:
let a = &[Some(1), Some(2), Some(3), None, Some(4)];
let mut sum = 0;
for &j in a.iter() {
match j {
Some(x) => sum += x,
None => ()
}
}
assert_eq!(sum, 1+2+3+4);
希望有帮助 for
将a
中的每个元素绑定到模式&Some(x)
-因此当a
的第一个元素为&Some(1)
时,x
变为1。但是None
与模式&Some(x)
不匹配,因此绑定无法成功。Rust从文本值推断a
的类型实际上是选项
(包含部分()
或无
)的类型,并且您的模式没有涵盖所有可能性。它不是等待运行时告诉您它不知道该做什么,而是在编译时抛出一个错误
据我所知(主要是阅读了本教程),我认为您需要做如下工作:
for &thing in a.iter() {
match thing {
Some(x) => sum += x
None => /* do nothing */
}
}
for
循环的模式本质上具有与let
相同的限制:它必须是无可辩驳的,也就是说,它永远不能不匹配
无可辩驳的模式的例子有&
、元组、结构和单变量枚举。其他模式(如多变量枚举或文本)不能保证总是匹配,因为该类型允许模式未涵盖的值
for
构造本质上是一个宏,其解压如下(它在宏展开的同一过程中解压,您可以看到它手动运行rustc,并使用--相当扩展的):
这是一个正常的匹配
,即手臂必须详尽无遗(覆盖所有可能性),因此如果
只是&Some())
,那么Some(&None)
可能性就不包括在内
(Some
arm本质上等同于Some(value)=>{let=value;..
。现在想想,这实际上可能是一种可以提供更好错误消息的去糖化:我存档了。)以下功能也可以工作:
use std::iter::AdditiveIterator;
fn main() {
let a = &[Some(1), Some(2), Some(3), None, Some(4)];
let sum = a.iter().filter_map(|x| *x).sum();
assert_eq!(sum, 1+2+3+4);
}
这也适用于:
let sum = a.iter().fold(0, |s, e| s + e.unwrap_or(0));
我同意这是一种表达相同代码的方式,而且更清晰。但我的问题是&Some(\ux)在for循环的“pat”部分给出了含义。这将是您建议的一个简写。我不是100%确定这一点,因为我仍在学习rust:pat是rust试图匹配的模式。此匹配必须是详尽的,以便您的代码进行编译。这确保没有错误。但是对于选项情况,我可以看到类似于cou的内容我猜某种宏可以创建类似的东西,但我不确定。希望能有所帮助。
let sum = a.iter().fold(0, |s, e| s + e.unwrap_or(0));