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));