You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust无法借用已声明变量?循环中所有权转移引发编译错误

Rust借用机制问题:解决循环存入字符串到Vec的编译错误

问题背景

需要实现一个循环:输入名字直到输入"exit",将名字存入Vec并打印Vec内容,原代码如下:

use std::io;

fn main() { 

    let mut name = String::new();
    let mut vec = Vec::new();

    while name.ne("exit") {
        print!("Enter a name"); 
        io::stdin().read_line(&mut name).expect("failed to readline");
    
        print!("You entered {}", name); 

        vec.push(name); 
        println!("length of vector is {}", vec.len());

        for i in &vec {
            println!("name in vector is {}", i);
        }  
    }

}

首次编译错误

执行cargo build后报错:

~/rust/vectors/src$ cargo build
   Compiling vectors v0.1.0 (rust/vectors)
error[E0382]: borrow of moved value: `name`
  --> src/main.rs:8:11
   |
5  |     let mut name = String::new();
   |         -------- move occurs because `name` has type `String`, which does not implement the `Copy` trait
...
8  |     while name.ne("exit") {
   |           ^^^^^^^^^^^^^^^ value borrowed here after move
...
14 |         vec.push(name); 
   |                  ---- value moved here, in previous iteration of loop

For more information about this error, try `rustc --explain E0382`.
error: could not compile `vectors` due to previous error

错误核心:String未实现Copy trait,vec.push(name)会将name的所有权完全转移给Vec,下一次循环时name已无所有权,无法被访问。

错误修改尝试及新问题

将while循环改为while &mut name.ne("exit")后,出现新错误:

Compiling vectors v0.1.0 (rust/vectors)
error[E0308]: mismatched types
 --> src/main.rs:8:11
  |
8 |     while &mut name.ne("exit") {
  |           ^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `&mut bool`
  |
help: consider removing the borrow
  |
8 -     while &mut name.ne("exit") {
8 +     while name.ne("exit") {
  | 

For more information about this error, try `rustc --explain E0308`.
error: could not compile `vectors` due to previous error

错误核心:ne方法返回bool类型,取可变引用后得到&mut bool,而while条件要求的是原始bool类型,类型不匹配。

解决方案

方案1:循环内创建新字符串变量

每次循环创建新的name变量,避免所有权转移导致的失效问题,同时处理输入中的换行符确保退出逻辑正确:

use std::io;

fn main() {
    let mut vec = Vec::new();

    loop {
        let mut name = String::new();
        print!("Enter a name: ");
        io::stdin().read_line(&mut name).expect("failed to readline");
        
        // 去除输入末尾的换行符和空白字符
        let name_trimmed = name.trim();
        if name_trimmed == "exit" {
            break;
        }

        println!("You entered {}", name);
        vec.push(name);
        println!("Length of vector is {}", vec.len());

        for i in &vec {
            println!("Name in vector is {}", i);
        }
    }
}

说明:循环内新建的name变量在push后所有权转移给Vec,下一次循环重新创建即可;trim()处理后能正确识别"exit"输入,避免因换行符导致的退出失效。

方案2:克隆字符串保留原变量所有权

复用同一个name变量,通过clone()创建副本存入Vec,同时清空变量内容用于下一次输入:

use std::io;

fn main() {
    let mut name = String::new();
    let mut vec = Vec::new();

    loop {
        name.clear(); // 清空上一次输入的内容
        print!("Enter a name: ");
        io::stdin().read_line(&mut name).expect("failed to readline");
        
        let name_trimmed = name.trim();
        if name_trimmed == "exit" {
            break;
        }

        println!("You entered {}", name);
        vec.push(name.clone()); // 克隆副本,原name所有权保留
        println!("Length of vector is {}", vec.len());

        for i in &vec {
            println!("Name in vector is {}", i);
        }
    }
}

说明:name.clear()清空原有内容,clone()生成字符串副本存入Vec,原name变量始终拥有所有权,可重复使用。

内容的提问来源于stack exchange,提问作者D.Zou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 15:54:36