rust 关于创建对String的长期引用的困惑

zwghvu4y  于 2024-01-08  发布在  其他
关注(0)|答案(2)|浏览(126)

我试图提高我的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做到这一点。

vlf7wbxs

vlf7wbxs1#

如果b的类型是&String而不是String,则没有优势。

fn main() {
    let test_lines = "line 1
            line 2
            line 3
            line 4
            line 5";
    let mut a;
    let mut b = String::new();
    let mut temp;

    for line in test_lines.lines() {
        a = b;
        temp = line.trim().to_string();  // could be assigned directly to b
        b = temp;

        println!("{a} - {b}");
    }
}

字符串
Playground

wrrgggsh

wrrgggsh2#

rust编译器在这里给你的错误消息可能有点令人困惑,因为它给你的是问题在源代码中出现的顺序,而不是循环的执行顺序。
让我们在头脑中执行循环,一步一步地执行(仅限相关部分)。
1.在第一次迭代中
1.使用to_string创建一个新的所有者字符串,并将其存储在temp中。
1.然后将对该字符串的引用存储在b中。(“temp is borrowed here”)
1.在第二次迭代中
1.将引用从b复制到a
1.修改temp(“temp被分配到这里,但它已经被借用”)
在某些情况下,这实际上是可以做到的,例如temp被借用,但是借用没有被使用。但是你确实使用了借用,在下一步中:
1.使用修改前创建的atemp的引用(“borrow later used here”)
你的问题下面的注解告诉你,你不能在一个变量中存储多个字符串(与展开的示例相比,它有三个let temp s,这意味着结尾处同时有三个字符串)。这是关于问题所在的提示,但实际上这不是rustc抱怨的问题;它只是抱怨你引用了一个变量,修改了这个变量,将展开示例中的第二个和第三个let temp =更改为temp =,您将看到相同的错误消息(以更容易理解的顺序)。

相关问题