为什么 map 和 map_err 捕获相同的变量?
Why does map and map_err capture the same variable?
我正在构建一个连锁的未来
ActorFuture<Item = Vec<String>, Error = Vec<String>, Actor = Self>
成功后,它将拥有所有与 .and_then
链接的期货的字符串输出向量。第一次错误处理将停止,我想 return 成功的期货输出和最终(失败的)未来错误。我想使用相同的向量来处理两条路径:ok 和 err。但是编译器抱怨:
242 | .map(|o| {v.push(o); v})
| --- value moved (into closure) here
243 | .map_err(|e| {v.push(format!("{}", e)); v})
| ^ value captured here after move
这是为什么?是否可以同时进入 map
和 map_err
?在我的理解中,这永远不应该发生。
一个例子:
#[test]
fn test_map_and_map_err() {
let mut v = Vec::new();
Ok("foo".to_string())
.map(|i| { v.push(i); v })
.map_err(|e: String| { v.push(e); v });
}
error[E0382]: capture of moved value: `v`
--> src/lib.rs:6:32
|
5 | .map(|i| { v.push(i); v })
| --- value moved (into closure) here
6 | .map_err(|e: String| { v.push(e); v });
| ^ value captured here after move
|
= note: move occurs because `v` has type `std::vec::Vec<std::string::String>`, which does not implement the `Copy` trait
编译器不知道传递给map
和map_err
的闭包是互斥的。即使这样做了,它也无法构造两个拥有相同值的闭包。
您需要对编译器使用 "transparent" 的构造,例如 match
:
#[test]
fn test_map_and_map_err() {
let mut v = Vec::new();
let r = Ok("foo".to_string())
.map(|i| v.push(i))
.map_err(|e: String| v.push(e));
match r {
Ok(()) => Ok(v),
Err(()) => Err(v),
};
}
或者您可以换出该值:
#[test]
fn test_map_and_map_err() {
use std::mem;
let mut v = Vec::new();
Ok("foo".to_string())
.map(|i| {
v.push(i);
mem::replace(&mut v, vec![])
}).map_err(|e: String| {
v.push(e);
mem::replace(&mut v, vec![])
});
}
我正在构建一个连锁的未来
ActorFuture<Item = Vec<String>, Error = Vec<String>, Actor = Self>
成功后,它将拥有所有与 .and_then
链接的期货的字符串输出向量。第一次错误处理将停止,我想 return 成功的期货输出和最终(失败的)未来错误。我想使用相同的向量来处理两条路径:ok 和 err。但是编译器抱怨:
242 | .map(|o| {v.push(o); v})
| --- value moved (into closure) here
243 | .map_err(|e| {v.push(format!("{}", e)); v})
| ^ value captured here after move
这是为什么?是否可以同时进入 map
和 map_err
?在我的理解中,这永远不应该发生。
一个例子:
#[test]
fn test_map_and_map_err() {
let mut v = Vec::new();
Ok("foo".to_string())
.map(|i| { v.push(i); v })
.map_err(|e: String| { v.push(e); v });
}
error[E0382]: capture of moved value: `v`
--> src/lib.rs:6:32
|
5 | .map(|i| { v.push(i); v })
| --- value moved (into closure) here
6 | .map_err(|e: String| { v.push(e); v });
| ^ value captured here after move
|
= note: move occurs because `v` has type `std::vec::Vec<std::string::String>`, which does not implement the `Copy` trait
编译器不知道传递给map
和map_err
的闭包是互斥的。即使这样做了,它也无法构造两个拥有相同值的闭包。
您需要对编译器使用 "transparent" 的构造,例如 match
:
#[test]
fn test_map_and_map_err() {
let mut v = Vec::new();
let r = Ok("foo".to_string())
.map(|i| v.push(i))
.map_err(|e: String| v.push(e));
match r {
Ok(()) => Ok(v),
Err(()) => Err(v),
};
}
或者您可以换出该值:
#[test]
fn test_map_and_map_err() {
use std::mem;
let mut v = Vec::new();
Ok("foo".to_string())
.map(|i| {
v.push(i);
mem::replace(&mut v, vec![])
}).map_err(|e: String| {
v.push(e);
mem::replace(&mut v, vec![])
});
}