繁体   English   中英

在 Rust 中隐藏并与借用检查器作斗争

[英]Shadowing in Rust and Fighting the Borrow Checker

每次我接受用户输入时,我都会创建一个新变量(通过阴影)来获取输入。 我认为这是低效的,而不是阴影的目的,我还能如何有效地重用变量输入?

如果没有阴影,它会导致错误cannot borrow "input" as mutable because it is also borrowed as immutable 据我了解,获取用户输入需要一个可变引用。

use std::io; // Import for IO

fn main() {
    let name: &str;                 // Variables
    let balance: f32;               // Variables
    let interest: f32;              // Variables
    let mut input = String::new();  // Variables

    println!("Please enter your name: "); // Print
    io::stdin().read_line(&mut input).expect("failed to read from stdin");
    name = input.trim();
    println!("Please enter your bank account balance: "); // Print

    loop {
        let mut input = String::new(); // Remove this and I get an error
        io::stdin().read_line(&mut input).expect("failed to read from stdin");

        match input.trim().parse::<f32>() {
            Ok(_) => {
                balance = input.trim().parse().unwrap();
                break;
            },
            Err(_) => println!("Your balance cannot contain letters or symbols"),};
        }
    }

    println!("Please enter your interest rate percent: "); // Print
     
    loop {
        let mut input = String::new(); // Remove this and I get an error
        io::stdin().read_line(&mut input).expect("failed to read from stdin");
    
        match input.trim().parse::<f32>() {
            Ok(_) =>  {   
                interest = input.trim().parse().unwrap();
                break;
            },
            Err(_) => println!("Your balance cannot contain letters or symbols"),};       
        }
    }

    println!("{}, your gain from interest is : ${}", name, (interest * balance * 0.01)); // Print
}

来自 Java,我对借用的工作方式以及何时隐藏是一个好主意感到困惑。 我知道旧值仍然存在,并且任何对它的引用都意味着如果您不再需要旧值,那么您将无缘无故地占用资源。 任何建议都有帮助,谢谢。

该错误告诉您问题:

error[E0502]: cannot borrow `input` as mutable because it is also borrowed as immutable
  --> src/main.rs:20:27
   |
13 |     name = input.trim();
   |            ----- immutable borrow occurs here
...
20 |     io::stdin().read_line(&mut input).expect("failed to read from stdin");
   |                           ^^^^^^^^^^ mutable borrow occurs here
...
47 |     println!("{}, your gain from interest is : ${}", name, (interest * balance * 0.01)); //Print
   |                                                      ---- immutable borrow later used here

input.trim()创建一个对 input 的不可变引用并将其存储在name 如果删除String::new()调用,那么您正在调用io::stdin().read_line(&mut input) ,它接受对输入的可变引用,但在name变量中仍然存在对输入的不可变引用。

在 Rust 中,不允许不可变引用和可变引用同时存在,因此编译器会报错。

你不能真正在这里重用变量,你需要克隆或做你正在做的事情并完全创建一个新的字符串。

HexCoder 的回答解释了您不能在input重用String ,因为它是由name借用的。 但是,为了使其可重用,您需要做的就是将input.trim()复制到一个带有自己的缓冲区的新String

let name: String = input.trim().into();

由于name不再借用input ,您可以擦除input并重新使用其缓冲区。 要擦除字符串,请使用String::clear

input.clear(); // instead of `input = String::new();`

这是一个更完整的示例,其中我还使用模式绑定来避免对input两次解析,并将balanceinterest的声明移至可以立即初始化的位置。

也可以看看

变量阴影有一些微妙之处,尤其是当您考虑编译器优化时; 这些问题也可能有用:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM