【发布时间】:2019-10-27 23:06:10
【问题描述】:
我想了解为什么下面示例中的外部堆栈变量data 不需要与闭包一起使用move 关键字。
示例取自Curl crate,documentation 声明write_function 的生命周期取自transfer 变量,因此闭包可以访问堆栈变量data不动它。
这是来自文档的引用:
请注意,此函数的生命周期限制是'静态的,但这通常过于严格。要使用堆栈数据,请考虑调用传输方法,然后使用 write_function 配置可以引用堆栈本地数据的回调。
见:https://docs.rs/curl/0.4.6/curl/easy/struct.Easy.html#method.write_function
use curl::easy::Easy;
let mut data = Vec::new();
let mut handle = Easy::new();
handle.url("https://www.rust-lang.org/").unwrap();
{
let mut transfer = handle.transfer();
transfer.write_function(|new_data| {
data.extend_from_slice(new_data);
Ok(new_data.len())
}).unwrap();
transfer.perform().unwrap();
}
println!("{:?}", data);
为什么会这样?
或者,如果我尝试直接使用handle 中的write_function,则会收到data 已被移动的借用错误。
这是一个不起作用的示例,我理解它为什么不起作用。我很困惑为什么上面的方法可以代替。
use curl::easy::Easy;
let mut data = Vec::new();
let mut handle = Easy::new();
handle.url("https://www.rust-lang.org/").unwrap();
handle.write_function(move |new_data| {
data.extend_from_slice(new_data);
Ok(new_data.len())
}).unwrap();
handle.perform().unwrap();
println!("{:?}", data);
// ^^^^ error because it was moved
【问题讨论】:
-
它的工作是因为 FnMut,我强烈建议您阅读 doc.rust-lang.org/std/ops/trait.FnMut.html 并提高您对不同闭包类型(Fn、FnOnce、FnMut)的了解,这可以使您的代码更加清晰。