Rust报错E0596:无法将`&`引用数据作为可变借用的解决方法
错误原因
你对Rust引用的可变性修饰位置理解错了:
你写的参数声明mut phrase: &String,mut修饰的是phrase这个变量本身,意思是你可以让phrase这个变量重新指向其他字符串,但它持有的是对不可变String的共享引用,根本没有修改引用指向的内存数据的权限。std::io::stdin().read_line()方法要求传入&mut String类型的参数(指向可修改字符串的独占可变引用),你传入&mut phrase得到的是&mut &String类型,本质还是只能访问不可变的字符串数据,自然无法借给需要可变权限的read_line,触发E0596错误。
这里要记清楚Rust可变性修饰的位置差异:
mut 变量名: 类型:仅变量本身可重新绑定赋值,不影响指向内容的可变性&mut 类型:可变引用,可通过该引用修改指向的内存内容
修复步骤
- 调整参数设计
你当前代码里phrase参数完全是多余的——函数第一行就会读取用户输入覆盖phrase的原有值,根本不需要外部传入初始值,直接在函数内部创建空字符串接收输入更合理。如果确实需要把用户输入回写到调用方传入的字符串,把参数声明从mut phrase: &String改成phrase: &mut String即可,&mut写在引用符号后面才代表指向的字符串内容可修改。 - 清理冗余代码
你多处写的.replace("\r", "").clone().to_string()属于无意义冗余:replace()方法本身就返回新的String,不需要再调用clone()、to_string()做重复拷贝。 - 修复原有逻辑bug
你当前的代码存在两个隐蔽逻辑问题:一是只去除了回车符\r没去掉末尾的换行符\n,会导致哈希比对永远失败;二是else分支的循环就算用户后续输入正确口令,也只会跳出循环直接返回None,不会执行解密逻辑;三是循环读输入前没有清空历史内容,会导致每次输入都追加到旧字符串后面。
修复后可编译运行的参考代码
pub use magic_crypt::{new_magic_crypt, MagicCryptTrait, MagicCryptError}; // 假设这是你项目中已实现的哈希函数 fn hash_string(s: &str) -> String { todo!() } pub fn magic_decrypt(hash: &String, decrypt: String) -> Option<Result<String, MagicCryptError>> { // 内部创建字符串接收输入,不需要外部传入phrase参数 let mut phrase = String::new(); loop { println!("Please insert your decryption phrase: "); phrase.clear(); // 每次读输入前清空上次的内容 std::io::stdin() .read_line(&mut phrase) .expect("Failed to read line"); // 统一去掉末尾的回车、换行符,比全量replace效率更高 let input_phrase = phrase.trim_end_matches(['\r', '\n']); if hash_string(input_phrase) == *hash { println!("Success, you've entered the correct phrase, decrypting..."); return Some( new_magic_crypt!(input_phrase, 256).decrypt_base64_to_string(&decrypt) ); } println!("Failed to enter the correct phrase, please try again."); } }
如果你一定要保留phrase作为入参的写法,只需要把参数改成phrase: &mut String,调用read_line时直接传phrase即可,不需要额外写&mut phrase,调用该函数时也要传入可变引用:
let mut input_buf = String::new(); let res = magic_decrypt(&mut input_buf, &target_hash, encrypted_data);
内容的提问来源于stack exchange,提问作者user19316228
相关产品推荐
相关产品推荐

