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
的东西。(我知道我可以很容易地通过使用字符串文字而不是将其转换为"所拥有的"字符串来修复此特定示例。这是一个玩具示例,重新生成此问题-在我的"真实"代码中,字符串变量是从文件中读取的,因此我显然不能使用字面意义上的值。)
更神秘的是,以下对该函数的变异,在我看来应该遇到同样的问题,但它却正常工作:
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的所有权/借用规则如何工作几乎没有掌握,尽管我认为我至少了解基础知识。因此,如果有人能给我一个相对清晰和全面的指南,解释所有这些示例中正在发生的事情,并说明如何以一些简单的方式修复失败的示例,我将非常感激!
.to_owned
来修复问题,但是一直无法使其正常工作。现在我已经解决了,虽然我的其他几个函数都必须从接受&str
切片转换为拥有的String
。我想这是不可避免的(我现在明白了 Rust 书中的 部分,我以为它是说始终优先使用字符串切片,但我现在看到这只适用于借用的String
,而不是拥有的)。再次感谢。 - Robin Zigmond&String
更改为&str
,因为&str
更通用。 - Aplet123