解决Rust所有权问题:document借用值生命周期不足报错
问题原因
核心问题是document是fetch_links函数内部的局部变量,函数执行完毕后它会被销毁。但你从element.value().attr("href")拿到的&str是指向document内部数据的引用,这些引用的生命周期和document绑定,可函数返回的Vec<&'a str>要求引用的生命周期至少是'a——这比document的生命周期长得多,编译器不允许这种悬垂引用出现,所以报了错。
解决方案:返回拥有所有权的
String 最直接的解决办法是把函数返回类型从Vec<&'a str>改成Vec<String>,这样每个href都会被转换成独立的、拥有所有权的字符串,不再依赖局部变量的生命周期:
pub fn start(url: String) -> Vec<String> { let resp = reqwest::blocking::get(url).unwrap(); let mut buf = "".to_string(); if resp.headers()["content-encoding"] == "gzip" { let bytes = resp.bytes().unwrap(); let mut decoder = GzDecoder::new(&bytes[..]); decoder.read_to_string(&mut buf).unwrap(); } else { println!("bad content-encoding"); } let anchors: Vec<String> = vec![]; fetch_links(&buf, anchors) } fn fetch_links(buf: &str, mut anchors: Vec<String>) -> Vec<String> { let document = Html::parse_document(&buf); let anchor = Selector::parse("a").unwrap(); for element in document.select(&anchor) { if let Some(href) = element.value().attr("href") { anchors.push(href.to_string()); } } anchors }
为什么返回引用的思路走不通?
如果你想坚持返回引用,调整生命周期参数也没用——因为Html::parse_document会把输入的字符串解析成自己的内部DOM结构,attr返回的引用是指向document的,不是原始的buf。哪怕buf的生命周期足够长,document作为局部变量还是会在函数结束时销毁,引用依然会变成悬垂引用,编译器绝对不会放行。
内容的提问来源于stack exchange,提问作者Antony
相关产品推荐
相关产品推荐

