我具有以下功能:
pub fn map_option<A: 'static, B: 'static> (a2b: Box<Fn(A) -> B>) -> Box<Fn(Option<A>) -> Option<B>> {
Box::new(move |opt_a: Option<A>| {
opt_a.map(|a| a2b(a))
})
}
但是,这很难写。我从简单的东西开始就行了,但是我不明白为什么它不行。
这是我的第一个版本:
pub fn map_option_1<A: 'static, B: 'static> (a2b: Box<Fn(A) -> B>) -> Box<Fn(Option<A>) -> Option<B>> {
Box::new(|opt_a: Option<A>| {
opt_a.map(a2b)
})
}
这给了我以下错误:
error[E0507]: cannot move out of `a2b`, a captured variable in an `Fn` closure
--> src/lib.rs:11:19
|
9 | pub fn map_option_1<A: 'static, B: 'static> (a2b: Box<Fn(A) -> B>) -> Box<Fn(Option<A>) -> Option<B>> {
| --- captured outer variable
10 | Box::new(|opt_a: Option<A>| {
11 | opt_a.map(a2b)
| ^^^ move occurs because `a2b` has type `std::boxed::Box<dyn std::ops::Fn(A) -> B>`, which does not implement the `Copy` trait
我认为我可能需要move
闭包,以便它获得a2b
的所有权:
pub fn map_option_2<A: 'static, B: 'static> (a2b: Box<Fn(A) -> B>) -> Box<Fn(Option<A>) -> Option<B>> {
Box::new(move |opt_a: Option<A>| {
opt_a.map(a2b)
})
}
但是,这也不起作用。它失败,并显示以下消息:
error[E0507]: cannot move out of `a2b`, a captured variable in an `Fn` closure
--> src/lib.rs:17:19
|
15 | pub fn map_option_2<A: 'static, B: 'static> (a2b: Box<Fn(A) -> B>) -> Box<Fn(Option<A>) -> Option<B>> {
| --- captured outer variable
16 | Box::new(move |opt_a: Option<A>| {
17 | opt_a.map(a2b)
| ^^^ move occurs because `a2b` has type `std::boxed::Box<dyn std::ops::Fn(A) -> B>`, which does not implement the `Copy` trait
此错误消息说a2b
没有实现Copy
,我想这很有意义,但是我不知道如何解决它。
出于绝望,我尝试了以下操作:
pub fn map_option_3<A: 'static, B: 'static> (a2b: Box<Fn(A) -> B>) -> Box<Fn(Option<A>) -> Option<B>> {
Box::new(|opt_a: Option<A>| {
opt_a.map(|a| a2b(a))
})
}
这至少给了我一个不同的错误:
error[E0373]: closure may outlive the current function, but it borrows `a2b`, which is owned by the current function
--> src/lib.rs:22:14
|
22 | Box::new(|opt_a: Option<A>| {
| ^^^^^^^^^^^^^^^^^^ may outlive borrowed value `a2b`
23 | opt_a.map(|a| a2b(a))
| --- `a2b` is borrowed here
|
note: closure is returned here
--> src/lib.rs:22:5
|
22 | / Box::new(|opt_a: Option<A>| {
23 | | opt_a.map(|a| a2b(a))
24 | | })
| |______^
help: to force the closure to take ownership of `a2b` (and any other referenced variables), use the `move` keyword
|
22 | Box::new(move |opt_a: Option<A>| {
| ^^^^^^^^^^^^^^^^^^^^^^^
我猜,所有权问题很有意义。这就是导致我找到上述切实可行的解决方案的原因。
我尝试过的另一件事无效:
pub fn map_option_4<A: 'static, B: 'static> (a2b: Box<Fn(A) -> B>) -> Box<Fn(Option<A>) -> Option<B>> {
Box::new(|opt_a: Option<A>| {
opt_a.map(move |a| a2b(a))
})
}
这给了我以下错误:
error[E0507]: cannot move out of `a2b`, a captured variable in an `Fn` closure
--> src/lib.rs:29:19
|
27 | pub fn map_option_4<A: 'static, B: 'static> (a2b: Box<Fn(A) -> B>) -> Box<Fn(Option<A>) -> Option<B>> {
| --- captured outer variable
28 | Box::new(|opt_a: Option<A>| {
29 | opt_a.map(move |a| a2b(a))
| ^^^^^^^^ ---
| | |
| | move occurs because `a2b` has type `std::boxed::Box<dyn std::ops::Fn(A) -> B>`, which does not implement the `Copy` trait
| | move occurs due to use in closure
| move out of `a2b` occurs here
这里是每个功能的playground。
我认为我对生存期和所有权没有足够的了解,以了解为什么每个功能都会失败。
[我可以理解map_option_1
和map_option_3
如何失败,因为没有使用move
显式移动所有权,但是map_option_2
和map_option_4
失败令我感到惊讶。
我非常惊讶于map_option_2
不起作用,但是实际的map_option
函数起作用。对我来说,这些功能实际上是相同的。
为什么每个map_option_X
函数都无法编译 ??]
我认为我可能需要
move
闭包,以便获得a2b
的所有权