我如何装箱 Arc 和 Mutexed 变量?
How do I box Arc and Mutexed variables?
以下代码在闭包中获取一些变量,并且return是一个包含该数据的结构。
我无法 return 包含该数据的结构,即使我将结构装箱并克隆变量也是如此;他们不可能脱离这个范围。我考虑过使用回调闭包,但我真的不想那样做。有没有办法在没有回调的情况下将它们取出来?
pub fn get(addr: &str) -> std::io::Result<Box<Response>> {
use std::sync::{Arc, Mutex};
let mut crl = curl::easy::Easy::new();
crl.url(format!("{}{}", API_ADDR, addr).as_str()).unwrap();
// extract headers
let headers: Vec<String> = Vec::with_capacity(10);
let headers = Arc::new(Mutex::new(headers));
{
let headers = headers.clone();
crl.header_function(move |h| {
let mut headers = headers.lock().unwrap();
(*headers).push(String::from_utf8_lossy(h).into_owned());
true
})
.unwrap();
}
// extract body
let body = Arc::new(Mutex::new(String::with_capacity(1024)));
{
let body = body.clone();
crl.write_function(move |b| {
let mut body = body.lock().unwrap();
body.push_str(std::str::from_utf8(b).unwrap());
Ok(b.len())
})
.unwrap();
}
crl.perform().unwrap();
Ok(Box::new(Response {
resp: body.lock().unwrap().clone(),
headers: headers.lock().unwrap().clone(),
}))
}
关键错误好像是这个:
error[E0597]: `body` does not live long enough
--> src/lib.rs:85:15
|
85 | resp: body.lock().unwrap().clone(),
| ^^^^ borrowed value does not live long enough
...
89 | }
| - `body` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
headers 对象也是如此。
我删除了你的很多代码,得到了一个简化的复制器:
use std::sync::{Arc, Mutex};
pub struct Response {
resp: String,
headers: Vec<String>,
}
pub fn get(addr: &str) -> std::io::Result<Box<Response>> {
let headers: Vec<String> = Vec::with_capacity(10);
let headers = Arc::new(Mutex::new(headers));
let body = Arc::new(Mutex::new(String::with_capacity(1024)));
Ok(Box::new(Response {
resp: body.lock().unwrap().clone(),
headers: headers.lock().unwrap().clone(),
}))
}
我认为这与最终 Ok(Box::new(...))
return 值中构造的临时变量的生命周期有关。
我能够通过将 lock/unwrap 拉到外面来编译它。
let body = body.lock().unwrap();
let headers = headers.lock().unwrap();
Ok(Box::new(Response {
resp: body.clone(),
headers: headers.clone(),
}))
根据 中给出的更全面的解释,我发现您可以将其写成
return Ok(Box::new(Response {
resp: body.lock().unwrap().clone(),
headers: headers.lock().unwrap().clone(),
}));
即添加一个明确的 return
和一个尾随分号。虽然我有一种感觉 clippy 可能会说它的风格不好。
以下代码在闭包中获取一些变量,并且return是一个包含该数据的结构。
我无法 return 包含该数据的结构,即使我将结构装箱并克隆变量也是如此;他们不可能脱离这个范围。我考虑过使用回调闭包,但我真的不想那样做。有没有办法在没有回调的情况下将它们取出来?
pub fn get(addr: &str) -> std::io::Result<Box<Response>> {
use std::sync::{Arc, Mutex};
let mut crl = curl::easy::Easy::new();
crl.url(format!("{}{}", API_ADDR, addr).as_str()).unwrap();
// extract headers
let headers: Vec<String> = Vec::with_capacity(10);
let headers = Arc::new(Mutex::new(headers));
{
let headers = headers.clone();
crl.header_function(move |h| {
let mut headers = headers.lock().unwrap();
(*headers).push(String::from_utf8_lossy(h).into_owned());
true
})
.unwrap();
}
// extract body
let body = Arc::new(Mutex::new(String::with_capacity(1024)));
{
let body = body.clone();
crl.write_function(move |b| {
let mut body = body.lock().unwrap();
body.push_str(std::str::from_utf8(b).unwrap());
Ok(b.len())
})
.unwrap();
}
crl.perform().unwrap();
Ok(Box::new(Response {
resp: body.lock().unwrap().clone(),
headers: headers.lock().unwrap().clone(),
}))
}
关键错误好像是这个:
error[E0597]: `body` does not live long enough
--> src/lib.rs:85:15
|
85 | resp: body.lock().unwrap().clone(),
| ^^^^ borrowed value does not live long enough
...
89 | }
| - `body` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
headers 对象也是如此。
我删除了你的很多代码,得到了一个简化的复制器:
use std::sync::{Arc, Mutex};
pub struct Response {
resp: String,
headers: Vec<String>,
}
pub fn get(addr: &str) -> std::io::Result<Box<Response>> {
let headers: Vec<String> = Vec::with_capacity(10);
let headers = Arc::new(Mutex::new(headers));
let body = Arc::new(Mutex::new(String::with_capacity(1024)));
Ok(Box::new(Response {
resp: body.lock().unwrap().clone(),
headers: headers.lock().unwrap().clone(),
}))
}
我认为这与最终 Ok(Box::new(...))
return 值中构造的临时变量的生命周期有关。
我能够通过将 lock/unwrap 拉到外面来编译它。
let body = body.lock().unwrap();
let headers = headers.lock().unwrap();
Ok(Box::new(Response {
resp: body.clone(),
headers: headers.clone(),
}))
根据
return Ok(Box::new(Response {
resp: body.lock().unwrap().clone(),
headers: headers.lock().unwrap().clone(),
}));
即添加一个明确的 return
和一个尾随分号。虽然我有一种感觉 clippy 可能会说它的风格不好。