如何在Rust中获取嵌套之外的变量更改?

3

嘿,我很新于Rust和编程,我遇到了一些以前没有遇到过的问题。我尝试将用户输入变量的结果返回到屏幕上,但似乎一直没有成功,这是在外部嵌套之外的。

use std::{thread, time::Duration};

fn main(){
    let mut modifer = 0;
    let mut ModValue=0;
    let mut ModReason = "";

    let Y = "Y";
    let y = "y";
    let N = "N";
    let n = "n";

    print!("{esc}c", esc = 27 as char);
    let mut ModYN = String::new();
    println!("Are there any modifiers (Y/N)");
    std::io::stdin().read_line(&mut ModYN).unwrap();
    let ModYN = ModYN.trim();

    if ModYN == y || ModYN == Y{
        ModValue = 1;
        print!("{esc}c", esc = 27 as char);
        let mut modifer:f32=0.0;
        let mut input = String::new();
    
        //I'm attempting to get the input from the user to define a modifer reason and value
        println!("Please enter the modifer: ");
        std::io::stdin().read_line(&mut input).expect("Not a valid string");
        modifer = input.trim().parse().expect("Not a valid number");

        let mut ModReason = String::new();
        println!("Whats the modifer reason: ");
        std::io::stdin().read_line(&mut ModReason).unwrap();
        let ModReason = ModReason.trim();
    }
    //Then print those results to the screen outside of nesting
    print!("{esc}c", esc = 27 as char);
    println!("-Modifer-");
    println!("{}",&mut modifer);
    println!("-Modifer Reason-");
    println!("{}",&mut ModReason);
    thread::sleep(Duration::from_secs(5));
}

我尝试了许多方法,包括将其分配为可变的或者借用变量本身,甚至扩展嵌套超过打印结果。但我遇到了难题,真的需要一些帮助。

let声明一个变量,稍后需要使用= 来赋值。可以将let mut ModReason = String::new()放在let块之前,并使用ModReason = ModReason.trim().to_string()进行赋值(因为trim()返回&str,你需要拥有一个字符串) 。 - user4815162342
1个回答

2
你的代码存在几个缺陷,由于你的问题只涉及其中一个,所以我只会解释这个。这意味着下面的代码无法编译。但它会让你更接近解决方案。
我认为你的问题源于你不知道let var = valuevar = value之间的区别。这两个语句非常不同:第二个将value赋值给var,而第一个则创建一个新变量(如果已经有一个同名变量,则会进行遮蔽),然后对其进行赋值。这与下面的代码是相同的。
let var;
var = value;

因此,在循环中创建新变量ModReason时,您并没有修改循环外的那个变量:您实际上是在创建一个新变量,仅在if语句结束时将其销毁(而不使用它)。因此,解决方案是不要每次都创建一个新变量:

use std::{thread, time::Duration};

fn main(){
    let mut modifer = 0;
    let mut ModValue=0;
    let mut ModReason = "";

    let Y = "Y";
    let y = "y";
    let N = "N";
    let n = "n";

    print!("{esc}c", esc = 27 as char);
    let mut ModYN = String::new();
    println!("Are there any modifiers (Y/N)");
    std::io::stdin().read_line(&mut ModYN).unwrap();
    let ModYN = ModYN.trim();

    if ModYN == y || ModYN == Y{
        ModValue = 1;
        print!("{esc}c", esc = 27 as char);
        let mut modifer:f32=0.0;
        let mut input = String::new();
    
        //I'm attempting to get the input from the user to define a modifer reason and value
        println!("Please enter the modifer: ");
        std::io::stdin().read_line(&mut input).expect("Not a valid string");
        modifer = input.trim().parse().expect("Not a valid number");

        ModReason = String::new();
        println!("Whats the modifer reason: ");
        std::io::stdin().read_line(&mut ModReason).unwrap();
        ModReason = ModReason.trim();
    }
    //Then print those results to the screen outside of nesting
    print!("{esc}c", esc = 27 as char);
    println!("-Modifer-");
    println!("{}",&mut modifer);
    println!("-Modifer Reason-");
    println!("{}",&mut ModReason);
    thread::sleep(Duration::from_secs(5));
}

Rust会警告你(因为这样,你永远不会在循环之外分配给ModReason),如果你没有通过传递可变借用来打印ModReason,那么它就会发出警告(这是绝对没有用的:只需使用println!("{}", ModReason);)。

此外,Rust很可能会警告你有几个未使用的变量:如果你阅读了这些警告,你就可以理解你正在做错什么。


非常感谢您的帮助!您的答案很有效;如果您看到我的代码中有其他问题,我不介意您进行更详细的解释,因为我是新手,想要提高。我基本上是自学的,所以肯定会犯很多错误。如果没有的话,您知道我可以在哪里获得代码评估/总体建议吗?Stack和Reddit是我唯一的直接反馈来源。 - Xanthus
1
@Xanthus 首先,我认为编译器反馈是你能找到的最紧密的反馈循环。唯一的问题是当它警告你某些事情时,你可能不会立刻理解它的含义。直接搜索你不理解的编译器输出将会带你去看其他人做了和你一样的事情,并且有其他人解释了这个问题。除此之外,如果是关于错误的问题,Stack Overflow 是适合的,但是 Stack Overflow 的问题应该只涉及一个问题。如果你想要整个代码的审查,请尝试 codereview - jthulhu
另外,关于其他问题:首先,在尝试编译我给你的代码时,您会遇到类型错误。一旦您知道&strString之间的区别,就很容易修补它,如果您知道,请继续,否则请阅读相关资料。如果您对此有任何疑问,请随时提问。第二个问题是您的变量名称不是驼峰式命名法。此外,有些变量根本没有使用。 - jthulhu
此外,你的代码看起来几乎像是C语言代码:在函数开头,你通过填充虚拟值来“声明”变量,然后再“赋值”。在Rust中,你应该直接赋值。请记住,if ... { ... } else { ... }是一个表达式,所以你可以这样做:let mod_reason = if mod_yn == "Y" || ... { ... } else { ... }。这也会强制你更好地处理没有修饰符的情况,因为当前它只会打印一个空行。也许你可以使用Option<String>,只有在它是Some(...)时才打印修饰符。 - jthulhu
我可以继续谈论如何重构你的代码,但我觉得现在这样做对你并没有太大帮助。我认为你最好学习如何编写正确的代码,这将自然地引导你编写优秀的代码。简而言之,你能想象到的最好的反馈来源是编译器警告。如果你想要更多吹毛求疵的警告(我推荐这样做),可以尝试使用clippy。 - jthulhu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接