我试图提高我的Rust技能,但在如何获得引用和生命周期方面遇到了困惑。我试图从字符串中读取行,并通过几个变量“旋转”最后两行。
这是有效的:
fn main() {
let test_lines = "line 1
line 2
line 3
line 4
line 5";
let mut lines = test_lines.lines();
let mut a = &String::new();
let mut b = &String::new();
println!("{} - {}", a, b);
let temp = lines.next().unwrap().trim().to_string();
a = b;
b = &temp;
println!("{} - {}", a, b);
let temp = lines.next().unwrap().trim().to_string();
a = b;
b = &temp;
println!("{} - {}", a, b);
let temp = lines.next().unwrap().trim().to_string();
a = b;
b = &temp;
println!("{} - {}", a, b);
}
字符串
并产生:
-
- line 1
line 1 - line 2
line 2 - line 3
型
但是当我试着把它卷起来的时候:
fn main() {
let test_lines = "line 1
line 2
line 3
line 4
line 5";
let mut a = &String::new();
let mut b = &String::new();
let temp;
for line in test_lines.lines() {
a = b;
temp = line.trim().to_string();
b = &temp;
println!("{} - {}", a, b);
}
}
型
我得到这个错误:
error[E0506]: cannot assign to `temp` because it is borrowed
--> src/main.rs:68:9
|
68 | temp = line.trim().to_string();
| ^^^^ `temp` is assigned to here but it was already borrowed
69 | b = &temp;
| ----- `temp` is borrowed here
70 |
71 | println!("{} - {}", a, b);
| - borrow later used here
型
我已经阅读了explain
的错误,但我没有看到借用。(我发誓我看到这个工作一次.)
我尝试为输入的每一行创建String对象,并保留两个指向最后两行的指针(用于其他处理)。我希望当a和b被重新赋值时,“旧”行将被删除。
我可以很清楚地看到如何在C或C++中做到这一点,但不知道如何让Rust做到这一点。
2条答案
按热度按时间vlf7wbxs1#
如果
b
的类型是&String
而不是String
,则没有优势。字符串
Playground
wrrgggsh2#
rust编译器在这里给你的错误消息可能有点令人困惑,因为它给你的是问题在源代码中出现的顺序,而不是循环的执行顺序。
让我们在头脑中执行循环,一步一步地执行(仅限相关部分)。
1.在第一次迭代中
1.使用
to_string
创建一个新的所有者字符串,并将其存储在temp
中。1.然后将对该字符串的引用存储在
b
中。(“temp
is borrowed here”)1.在第二次迭代中
1.将引用从
b
复制到a
1.修改
temp
(“temp
被分配到这里,但它已经被借用”)在某些情况下,这实际上是可以做到的,例如
temp
被借用,但是借用没有被使用。但是你确实使用了借用,在下一步中:1.使用修改前创建的
a
到temp
的引用(“borrow later used here”)你的问题下面的注解告诉你,你不能在一个变量中存储多个字符串(与展开的示例相比,它有三个
let temp
s,这意味着结尾处同时有三个字符串)。这是关于问题所在的提示,但实际上这不是rustc抱怨的问题;它只是抱怨你引用了一个变量,修改了这个变量,将展开示例中的第二个和第三个let temp =
更改为temp =
,您将看到相同的错误消息(以更容易理解的顺序)。