可以将 Java Scanner 的输入分配给 while 循环条件内的变量吗?

Is it OK to assign the input from Java Scanner to a variable inside the while loop condition?

比如像这样。

while ((input = kb.nextInt()) != 0) {
            if (input % 2 == 0) {
                System.out.println("even");
            } else {
                System.out.println("odd");
            }

而不是像这样只检查条件内的输入变量的值并从循环内的 Scanner 获取数字:

while (input != 0) {
            input = kb.nextInt();
...code here...

只是想知道第一个是不好的做法还是类似的。

第二个没有定义用于测试条件的输入 input!=0 因此第一个是正确的,但如果您要使用第二种格式,我建议更改 while 循环到 do-while 循环。

您的两个代码示例并不等同,它们做的事情不同(第二个版本可能不符合您的要求)。 在第二个版本的循环之前,您需要在循环内添加另一个 if (input != 0) 并分配 input 。将赋值移动到末尾并在循环之前复制它也是一个可行的选择:

input = kb.nextInt();
while (input != 0) {
    if (input % 2 == 0) {
        System.out.println("even");
    } else {
        System.out.println("odd");
    }
    input = kb.nextInt();
}

而且这个版本中首行和末行的重复很可能是代码有点复杂的原因。这种类型的循环 loop ((x = input()) != 0) 可以在很多 C 代码中看到,但当您想在处理输入时减少代码重复时,有时也会在 Java 中看到 "required"。这是因为 nextInt returns 一个值并改变了底层状态。

使用 nextInt() 作为循环条件的一部分,虽然完全合法,但从处理因 错误输入 引起的错误的角度来看可能会出现问题。坐在键盘前输入数据的实际人类(Scanner 变量名 kb 似乎暗示这正是你在这里处理的)在数据输入质量方面是出了名的不可靠,所以错误的输入 是您应该做好的准备。

如果下一个可用输入不是整数的有效表示,

nextInt() 将抛出 InputMismatchException 异常。为了捕获和处理此异常,必须在 try 块内执行 nextInt() 调用。然而,由于 nextInt()while 循环控制条件的一部分,唯一的方法是将整个循环包含在 try 块中:

try {
    while ((input = kb.nextInt()) != 0){
       ...
    }
} catch (InputMismatchException ime){
     ...
}

不幸的是,这意味着 nextInt() 引发的任何异常都将终止 while 循环。如果你想在输入错误后继续处理用户输入,你必须提供一种重新启动 while 循环的方法,并继续重新启动它直到“真正的”用户信号结束 -已达到输入条件。您可能可以使用像这样的笨拙的解决方法来做到这一点:

boolean keepGoing = true;
while (keepGoing){
    try {
        while ((input = kb.nextInt()) != 0) {
           ...
        }
        keepGoing = false;  
    } catch (InputMismatchException ime) {
        String junk = kb.next();
        System.out.println("Didn't understand your input: " + junk);
        System.out.println("Please type a valid integer");
    }
}

但是根据循环内的 ... 代码在做什么,这种相对简单的解决方法可能不够充分;你可能需要更复杂和难以理解的东西。

但是通过将 nextInt() 调用移出循环的控制逻辑并移入循环体,您可以在从错误输入中恢复的选项方面获得相当大的灵活性。在循环体内使用 nextInt(),您现在可以在循环的一次迭代中完全捕获和处理任何异常,而不必终止循环本身:

do {
    try {
        input = kb.next();
        if (input != 0) {
            ...
        }
    } catch (InputMismatchedException ime) {
        String junk = kb.next();
        System.out.println("Didn't understand your input: " + junk);
        System.out.println("Please type a valid integer");
    } 
} while (input != 0);

您还可以选择完全避免异常,方法是使用 hasNextInt() 以确保在尝试使用 nextInt():

读取输入之前存在有效输入
for(;;) {
    if (!kb.hasNextInt()) {
        String junk = kb.next();
        System.out.println("Didn't understand your input: " + junk);
        System.out.println("Please type a valid integer");
    } else {
        input = kb.nextInt();
        if (input == 0) {
            break;
        else {
            ...
        }
    }
}