Rust中collect::<String>().trim()触发E0716错误的原因解析
为什么scraper库中单行调用trim()会触发E0716临时值释放错误?
问题场景
使用scraper库的ElementRef处理网页元素时,最初编写的单行代码触发了编译器错误:
let item_discount_price = item_discount_price_element.text().collect::<String>().trim();
编译器错误信息:
error[E0716]: temporary value dropped while borrowed --> src/main.rs:64:35 | 64 | let item_discount_price = item_discount_price_element.text().collect::<String>().trim(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement | | | creates a temporary which is freed while still in use 65 | let item_discount_price = item_discount_price.trim(); | -------------------------- borrow later used here | = note: consider using a `let` binding to create a longer lived valu
将代码拆分为两行后问题解决:
let item_discount_price = item_discount_price_element.text().collect::<String>(); let item_discount_price = item_discount_price.trim();
原因分析
核心在于Rust的临时值生命周期规则:
- 单行代码中,
collect::<String>()会创建一个匿名临时String对象,它没有被绑定到任何变量,生命周期仅局限于当前语句。 trim()方法返回的是这个临时String的引用(&str),但临时String会在语句执行完毕后立即被销毁,导致变量item_discount_price持有了指向已释放内存的悬空引用,违反了Rust的安全借用规则,因此编译器抛出E0716错误。
拆分后的代码则规避了这个问题:
- 第一行将
collect生成的String绑定到变量item_discount_price,该变量的生命周期会延续到当前作用域结束,不会被立即销毁。 - 第二行调用
trim()时,引用的是这个有明确生命周期的变量,不存在临时值提前释放的问题,因此可以正常编译。
内容的提问来源于stack exchange,提问作者WebOrCode
相关产品推荐
相关产品推荐

