gpt4 book ai didi

rust - 无法计算出从捕获成员变量的方法返回的闭包

转载 作者:行者123 更新时间:2023-11-29 08:26:12 25 4
gpt4 key购买 nike

我正在尝试为返回闭包 move 的结构实现一种方法 - 捕获其成员之一。基本原理是该成员是 Copy,因此闭包可以复制它并且不应绑定(bind)到结构生命周期。但是,它无法编译。

我希望 Rust 不会坚持 copying &self 引用,并通过保持对结构的引用将闭包生命周期与结构生命周期联系起来。当它没有编译时,我在错误消息中预料到这一点,但是 - 有点令人惊讶 - 我不确定那是确切的问题。
限制闭包的匿名生命周期是函数生命周期,它是 &self 的生命周期 - 而不是 self 的生命周期。当我 move 它时,我真的不明白问题出在哪里。

其实我有两个问题:
第一,为什么函数生命周期限制了我的闭包? (可能是我对错误消息的误解,我很乐意指出这一点)。
第二,如何在不将结构成员复制到 temp 变量(就在返回闭包之前)的情况下强制 move 并在闭包内部使用此 temp(有效,但在我看来不优雅)。

这是我的代码的简化版本:

struct Struct {
member: usize
}

impl Struct {
fn func(&self) -> Box<dyn Fn(usize)->usize> {
Box::new(move |argument: usize| {
self.member + argument
})
}
}

fn main() {
let s = Struct { member: 4 };
println!("{}", s.func()(5));
}

这在编译时给出:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src\main.rs:7:18
|
7 | Box::new(move |argument: usize| {
| __________________^
8 | | self.member + argument
9 | | })
| |_________^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 6:5...
--> src\main.rs:6:5
|
6 | / fn func(&self) -> Box<dyn Fn(usize)->usize> {
7 | | Box::new(move |argument: usize| {
8 | | self.member + argument
9 | | })
10| | }
| |_____^
= note: ...so that the types are compatible:
expected &Struct
found &Struct
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the expression is assignable:
expected std::boxed::Box<(dyn std::ops::Fn(usize) -> usize + 'static)>
found std::boxed::Box<dyn std::ops::Fn(usize) -> usize>

error: aborting due to previous error

最佳答案

The first, why does the function closure restricting my closure?

在方法内部,self 实际上是一个引用,因为它在方法签名中被声明为 &self。在 move 闭包内使用引用将 move 引用,但不会 move 基础值。

您看到的直接错误是因为从该方法返回的 Box 包含对结构的引用,但可能比结构长寿。如果允许这样做,闭包可以访问悬空指针,而 Rust 禁止这样做。

The second, how can I force the move of a struct member without copying it to a temp variable

为了避免在闭包中引用self,这是你必须要做的。您不能在不复制(或克隆)结构成员的情况下 move 它 - 否则该结构将不完整。这在 Rust 中是完全正常的事情。例如:

impl Struct {
fn func(&self) -> Box<dyn Fn(usize) -> usize> {
let temp = self.member;
Box::new(move |argument| {
temp + argument
})
}
}

如果在调用 func 后您不再需要该结构,那么您可以取 self 取而代之:

impl Struct {
fn func(self) -> Box<dyn Fn(usize) -> usize> {
Box::new(move |argument| {
self.member + argument
})
}
}

这是有效的,因为 self 被移到了闭包中。但是,它在其他任何地方都不再可用。

关于rust - 无法计算出从捕获成员变量的方法返回的闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57347091/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com