如何装箱Arc和Mutexed变量? [英] How do I box Arc and Mutexed variables?
问题描述
以下代码在闭包中获取一些变量,并返回包含该数据的结构.
The following code gets some variables in closures and returns a struct containing that data.
即使我对结构进行装箱并克隆变量,我也无法返回带有该数据的结构;他们不可能超出这个范围.我曾考虑过使用回调闭包,但是我真的不想这么做.有没有办法在没有回调的情况下将其删除?
I can't return the struct with that data even when I box the struct and clone the variables; they are impossible to take out of this scope. I thought about using a callback closure but I don't really want to do that. Is there any way to take those out without having a callback?
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(),
}))
}
推荐答案
关键错误似乎就是这个:
The key error seems to be this one:
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
标题对象相同.
通过存根大量代码,我能够得到一个简化的复制器:
I was able to get a simplified reproducer of this by stubbing out a lot of your code:
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(...))
返回值中构造的临时变量的生存期有关.
I think this has to do with the lifetimes of the temporary variables constructed in the final Ok(Box::new(...))
return values.
我可以通过将锁/拉开到外面来进行编译.
I was able to get it to compile by pulling the lock/unwrap outside.
let body = body.lock().unwrap();
let headers = headers.lock().unwrap();
Ok(Box::new(Response {
resp: body.clone(),
headers: headers.clone(),
}))
摘录自>为什么获得";寿命不足"返回值?我发现您可以将其写为
From the fuller explaination given in Why do I get "does not live long enough" in a return value? I've found that you can write this as
return Ok(Box::new(Response {
resp: body.lock().unwrap().clone(),
headers: headers.lock().unwrap().clone(),
}));
即添加显式return
和结尾的分号.虽然我有一种clip不休的感觉,但可能会说它的风格不好.
i.e. adding an explicit return
and a trailing semicolon. Though I have a feeling clippy might say that its bad style.
这篇关于如何装箱Arc和Mutexed变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!