移动闭包的特征?
Trait bound for move-closures?
有没有办法在 Rust 中使用特征绑定来区分 move
闭包和非 move
闭包?
对于上下文,我在我的程序中使用盒装闭包(Box + dyn Fn
特征),所以我需要担心生命周期,因为 IIUC 这些闭包可能引用堆栈。
我想知道我是否可以限制为盒装 move
-闭包,这样(希望)我可以避免处理生命周期,因为在这种情况下这些很快就会变得混乱。
或者是否有其他更好、更惯用的方法来达到相同的结果?
Is there a way to distinguish move closures from non-move closures using a trait bound in Rust?
“移动”在这里是一个转移注意力的问题。您可以在闭包 或 中通过引用借用变量,您可以 将引用移动 到闭包中,它们等价地相同。示例:
fn takes_closure<'a>(_closure: &'a dyn Fn() -> &'a i32) {}
fn main() {
let value = 123;
let value_ref = &value;
// captures value by borrowing it by reference
takes_closure(&|| &value);
// captures value_ref by moving it
takes_closure(& move || value_ref);
// what's the difference between the above 2 cases?
// answer: there isn't any
}
I'm using boxed closures in my program so I need to worry about lifetimes since IIUC these closures may reference the stack.
不,默认情况下盒装闭包得到一个隐式 'static
绑定。除非您明确设置自己的生命周期界限,否则您不能在盒装闭包中借用堆栈变量。
From Default trait object lifetimes in The Rust Reference:
If the trait has no lifetime bounds, then the lifetime is inferred in expressions and is 'static
outside of expressions.
例如,仅此函数签名就可以保证返回的闭包不会捕获任何非'static
外部引用或变量:
fn returns_boxed_closure() -> Box<dyn Fn()>;
// full desugared return type: Box<dyn Fn() + 'static>
如上所述,如果您希望盒装闭包不受 'static
生命周期的限制,您必须明确地对其进行注释。这是一个例子:
fn returns_boxed_closure<'a, T>(reference: &'a T) -> Box<dyn Fn() + 'a> {
Box::new(move || drop(reference))
}
上面的例子特别好,因为它表明即使你使用move关键字你仍然可以用它来创建一个盒装的非'static
生命周期的闭包。
总之,简而言之:您不必做任何特别的事情,盒装闭包会默认获得隐式 'static
绑定,并按您希望的方式工作,即您不必担心关于生命周期。
有没有办法在 Rust 中使用特征绑定来区分 move
闭包和非 move
闭包?
对于上下文,我在我的程序中使用盒装闭包(Box + dyn Fn
特征),所以我需要担心生命周期,因为 IIUC 这些闭包可能引用堆栈。
我想知道我是否可以限制为盒装 move
-闭包,这样(希望)我可以避免处理生命周期,因为在这种情况下这些很快就会变得混乱。
或者是否有其他更好、更惯用的方法来达到相同的结果?
Is there a way to distinguish move closures from non-move closures using a trait bound in Rust?
“移动”在这里是一个转移注意力的问题。您可以在闭包 或 中通过引用借用变量,您可以 将引用移动 到闭包中,它们等价地相同。示例:
fn takes_closure<'a>(_closure: &'a dyn Fn() -> &'a i32) {}
fn main() {
let value = 123;
let value_ref = &value;
// captures value by borrowing it by reference
takes_closure(&|| &value);
// captures value_ref by moving it
takes_closure(& move || value_ref);
// what's the difference between the above 2 cases?
// answer: there isn't any
}
I'm using boxed closures in my program so I need to worry about lifetimes since IIUC these closures may reference the stack.
不,默认情况下盒装闭包得到一个隐式 'static
绑定。除非您明确设置自己的生命周期界限,否则您不能在盒装闭包中借用堆栈变量。
From Default trait object lifetimes in The Rust Reference:
If the trait has no lifetime bounds, then the lifetime is inferred in expressions and is
'static
outside of expressions.
例如,仅此函数签名就可以保证返回的闭包不会捕获任何非'static
外部引用或变量:
fn returns_boxed_closure() -> Box<dyn Fn()>;
// full desugared return type: Box<dyn Fn() + 'static>
如上所述,如果您希望盒装闭包不受 'static
生命周期的限制,您必须明确地对其进行注释。这是一个例子:
fn returns_boxed_closure<'a, T>(reference: &'a T) -> Box<dyn Fn() + 'a> {
Box::new(move || drop(reference))
}
上面的例子特别好,因为它表明即使你使用move关键字你仍然可以用它来创建一个盒装的非'static
生命周期的闭包。
总之,简而言之:您不必做任何特别的事情,盒装闭包会默认获得隐式 'static
绑定,并按您希望的方式工作,即您不必担心关于生命周期。