我正在尝试使用Rust和tokio编写一个简单的HTTP服务器。
一切正常,直到我想发送响应为止。
代码如下:
use std::fs;
use std::sync::Arc;
use tokio::net::TcpListener; // 0.1.15
use tokio::prelude::*;
fn main() {
let addr = "0.0.0.0:8080".parse().unwrap();
let listener = TcpListener::bind(&addr).expect("unable to bind TCP listener");
let incoming = listener.incoming();
let server = incoming
.map_err(|e| eprintln!("accept failed = {:?}", e))
.for_each(|socket| {
println!(
"Connection established: from {:?} to {:?}",
socket.peer_addr(),
socket.local_addr()
);
let bytes = vec![0; 512];
let processor = tokio::io::read(socket, bytes)
.and_then(|(socket, bytes, _size)| {
println!("Request: {}", String::from_utf8_lossy(&bytes[..]));
let contents = fs::read_to_string("hello.html").unwrap();
let response = Arc::new(format!("HTTP/1.1 200 OK\r\n\r\n{}", contents));
let response = response.clone();
tokio::io::write_all(socket, response.as_bytes()).and_then(|_| Ok(()))
})
.map_err(|_| ());
tokio::spawn(processor);
Ok(())
});
tokio::run(server);
}
error[E0597]: `response` does not live long enough
--> src/main.rs:27:50
|
27 | tokio::io::write_all(socket, response.as_bytes()).and_then(|_| Ok(()))
| ^^^^^^^^ borrowed value does not live long enough
28 | })
| - `response` dropped here while still borrowed
我该如何声明响应以使生命足够长?
答案 0 :(得分:1)
正如我在评论中指出的那样:使用into_bytes
,而不是用Arc
包装并传递借来的字节数组。
@David:
但是我不明白为什么不使用弧线包裹。
Arc
计算内部对象的引用:
clone()
Arc
的所有者被删除时,它会减少引用。在您的情况下,名为Arc
的{{1}}的所有者。 response
在作用域中创建,并在相同作用域的末尾删除。创建时它的引用计数为1,删除后为0。但是,您已经在response
内将Arc
的引用传递到内存中之前。
请注意,Future
创建了一个write_all()
,并且Future
带有您的Future
的引用,该引用在Arc
被删除之前已从内存中删除。执行。
注释:Future
可以拥有借入或已移动值的所有权,它希望可以将其转换为通用参数WriteAll
。