为什么返回捕获复制类型的闭合时需要移动关键字?
fn foo(c: char) -> impl Fn() -> i32 {
|| bar(c)
}
fn bar(_: char) -> i32 {
42
}
引发错误的
error[E0597]: `c` does not live long enough
--> src/lib.rs:2:12
|
2 | || bar(c)
| -- ^ borrowed value does not live long enough
| |
| value captured here
3 | }
| -
| |
| `c` dropped here while still borrowed
| borrow later used here
我认为原始类型 char> char
默认情况;为什么我需要明确移动
it(移动|| bar(c)
)以获取编译代码?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是正确的,
char
是copy
,但是当执行副本时,棘手的恰好是。假装
复制
特质具有一种称为复制
的方法,类似于clone :: clone
。作为编译器所做的示例,您的关闭变为:闭合仅通过引用捕获
c
,因为在调用闭合时需要执行副本所需的一切。通过返回关闭,您将试图返回对本地的引用,这是禁止的。使用
移动
迫使闭合以按值捕获c
。另请参阅:
You are correct that the
char
isCopy
, but what's tricky is exactly when the copy is performed.Pretend that the
Copy
trait had a method calledcopy
, similar toClone::clone
. As an example of what the compiler does, your closure becomes:The closure only captures
c
by reference as that's all it needs to perform the copy when the closure is invoked. By returning the closure, you'd be trying to return the reference to the local, which is forbidden.Using
move
forces the closure to capturec
by value.See also:
实际上,因为
char
是Copy
才出现问题:默认情况下,Rust 闭包是“智能”的,因此它们捕获内容的方式如下尽可能不受限制。这意味着如果他们可以通过引用捕获,他们将通过引用捕获,如果他们不能但可以通过 mut ref 捕获,他们就会这样做,并且只有当他们不能时,他们才会通过值捕获(“移动”)。
在这里,因为
char
是Copy
它可以通过引用捕获然后复制到被调用者中。因此闭包会执行此操作,并且您必须告诉它按值捕获(使用move
关键字)。It's actually because
char
isCopy
that the issue occurs: by default, Rust closures are "smart", so the way they capture things is as unrestrictive as possible.This means if they can capture by reference they will capture by reference, if they can't but can capture by mut ref they'll do that, and only if they can't will they capture by value ("move").
Here, because
char
isCopy
it can be captured by reference then copied into the callee. And so the closure does that, and you have to tell it to capture by value (using themove
keyword) instead.