【发布时间】:2019-10-13 08:42:09
【问题描述】:
我正在尝试创建一个 ScopeRunner 类型,该类型可以将方法调用存储到实现 Scope 特征的类型的方法,如下所示:
trait Scope {
fn run(&self) -> String;
}
struct ScopeImpl;
impl Scope for ScopeImpl {
fn run(&self) -> String {
"Some string".to_string()
}
}
struct ScopeRunner {
runner: Box<dyn Fn() -> String>,
}
impl ScopeRunner {
fn new<S: Scope>(scope: S) -> Self {
ScopeRunner {
runner: Box::new(move || scope.run())
}
}
pub fn run(self) -> String {
(self.runner)()
}
}
fn main() {
let scope = ScopeImpl {};
let scope_runner = ScopeRunner::new(scope);
dbg!(scope_runner.run());
}
我希望由于ScopeRunner::new 创建了一个移动闭包,这将导致范围被移动到闭包中。但是借用检查器却给了我这个错误:
error[E0310]: the parameter type `S` may not live long enough
--> src/main.rs:21:30
|
20 | fn new<S: Scope>(scope: S) -> Self {
| -- help: consider adding an explicit lifetime bound `S: 'static`...
21 | ScopeRunner {runner: Box::new(move || scope.run())}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...so that the type `[closure@src/main.rs:21:39: 21:58 scope:S]` will meet its required lifetime bounds
--> src/main.rs:21:30
|
21 | ScopeRunner {runner: Box::new(move || scope.run())}
|
当我将 ScopeRunner::new 替换为只需要 ScopeImpl 的非通用版本时,此代码确实有效。
fn new(scope: ScopeImpl) -> Self {
ScopeRunner {
runner: Box::new(move || scope.run())
}
}
我不明白为什么这是不同的。在我看来,通用 Scope 的生命周期似乎与具体版本相同。
【问题讨论】:
-
在阅读了 Peter Halls 的出色答案并进行了更多研究后,我意识到我的问题可能与这个问题重复 stackoverflow.com/questions/40053550/…
标签: generics rust closures borrow-checker