【发布时间】:2016-07-05 08:39:01
【问题描述】:
我有一个结构 UrlShortener:
pub struct UrlShortener {
client: hyper::Client,
}
impl UrlShortener {
pub fn new() -> UrlShortener {
UrlShortener {
client: hyper::Client::new(),
}
}
pub fn get(&self, url: &str) -> Result<String, Error> {
let mut response = MyProvider.request(url, &self.client).send().unwrap();
/// ...
}
}
MyProvider 看起来像这样:
pub trait Provider {
fn name(&self) -> &str;
fn request(&self, url: &str, client: &hyper::Client) -> hyper::client::RequestBuilder;
}
pub struct MyProvider;
impl Provider for MyProvider {
fn name(&self) -> &str {
"myprovider"
}
fn request(&self, url: &str, client: &hyper::Client) -> hyper::client::RequestBuilder {
client.get(&format!("http://example.com/create.php?format=simple&url={}", url))
}
}
我第一次尝试编译它没有工作:
src/lib.rs:21:16: 21:19 error: cannot infer an appropriate lifetime for autoref due to conflicting requirements [E0495]
src/lib.rs:21 client.get(&format!("http://example.com/create.php?format=simple&url={}", url))
^~~
src/lib.rs:20:5: 22:6 help: consider using an explicit lifetime parameter as shown: fn request<'a>(&'a self, url: &str, client: &'a hyper::Client)
-> hyper::client::RequestBuilder
src/lib.rs:20 fn request(&self, url: &str, client: &hyper::Client) -> hyper::client::RequestBuilder {
src/lib.rs:21 client.get(&format!("http://example.com/create.php?format=simple&url={}", url))
src/lib.rs:22 }
error: aborting due to previous error
error: Could not compile `urlshortener`.
我已根据编译器的建议对其进行了更改,并且运行正常。
fn request<'a>(&'a self, url: &str, client: &'a hyper::Client) -> hyper::client::RequestBuilder {
client.get(&format!("http://example.com/create.php?format=simple&url={}", url))
}
这里的问题是它为什么有效?我在想什么:
Provider中self的'a生命周期与client: &hyper::Client的生命周期不同,因为这些对象位于不同的位置:MyProvider在堆栈上,client是结构的字段我使用的方法。
所以我认为编译器可以成功编译它,但它可能会导致运行时错误或崩溃。我错了吗?
从我的角度来看,“正确”的解决方案是:
fn request<'a, 'b>(&'a self, url: &str, client: &'b hyper::Client) -> hyper::client::RequestBuilder {
【问题讨论】:
标签: rust