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
相关产品推荐
相关产品推荐

