【发布时间】:2021-03-14 22:07:39
【问题描述】:
fn problem() -> Vec<&'static str> {
let my_string = String::from("First Line\nSecond Line");
my_string.lines().collect()
}
这会因编译错误而失败:
|
7 | my_string.lines().collect()
| ---------^^^^^^^^^^^^^^^^^^
| |
| returns a value referencing data owned by the current function
| `my_string` is borrowed here
我了解此错误的含义 - 它是为了阻止您返回对超出范围的值的引用。查看所涉及函数的类型签名后,问题似乎出在lines 方法上,该方法借用了它所调用的字符串。但为什么这很重要?我正在遍历字符串的行以获得部分的向量,我返回的是这个“新”向量,而不是任何会(非法)直接引用my_string。
(我知道我可以通过仅使用字符串文字而不是使用 String::from 转换为“拥有”字符串来非常轻松地修复这个特定示例。这是一个重现问题的玩具示例 - 在我的“真实" 编码字符串变量是从文件中读取的,所以我显然不能使用文字。)
对我来说更神秘的是,对我来说应该遇到同样问题的函数的以下变体可以正常工作:
fn this_is_ok() -> Vec<i32> {
let my_string = String::from("1\n2\n3\n4");
my_string.lines().map(|n| n.parse().unwrap()).collect()
}
原因不可能是map 做了一些魔术,因为这也失败了:
fn also_fails() -> Vec<&'static str> {
let my_string = String::from("First Line\nSecond Line");
my_string.lines().map(|s| s).collect()
}
我已经玩了很长时间了,在map 中尝试了各种不同的功能——有些通过,有些失败,老实说,我不知道有什么区别。所有这一切都让我意识到我对 Rust 的所有权/借用规则如何在不平凡的情况下工作知之甚少,尽管我认为我至少了解了基础知识。因此,如果有人能给我一个相对清晰和全面的指南,了解所有这些示例中发生了什么,以及如何以某种直接的方式修复那些失败的示例,我将非常感激!
【问题讨论】: