断开开关中的标签

2022-01-19 00:00:00 break switch-statement java-8 java

谢谢大家的帮助.使用我在前几章中学到的技能和您的建议,我能够让它发挥作用.非常感谢!

我决定尝试通过创建一个简单的文本冒险来巩固我从 Java:初学者指南中学到的东西.我即将开始第 4 章,其中涉及类和方法.前三章讨论了 if、for、while、do-while、switch、简单的键盘交互和 break/continue.

I decided to try cementing the things I have learned from Java: A Beginner's Guide by creating a simple text adventure. I am about to start Chapter 4 which involves classes and methods. The first three chapters have dealt with, if, for, while, do-while, switch, simple keyboard interaction, and break/continue.

我计划在每一章之后返回并编辑它以使用我学到的新技能.我几乎没有触及表面,我遇到了问题.

I plan on going back after every chapter and editing it to use the new skills that I have learned. I have barely scratched the surface and I am running into a problem.

// A basic, but hopefully, lengthy text adventure.

class TextAdventure
{
    public static void main(String args[])
    throws java.io.IOException
    {
        System.out.println("		 BASIC TEXT ADVENTURE");


        // variables I need, attributes, classes, character name, player's choice, gold
        int str = 0, inte = 0, chr = 0, con = 0, dex = 0, gold;
        char charName, choice;

        System.out.println("Welcome player! You are about to embark upon a quest in the form of a text adventure.");
        System.out.println("You will make choices, fight monsters, and seek treasure. Come back victorious and you");
        System.out.println("could quite possibly buy your way into nobility!");
        System.out.println();


caseChoice: {       
        System.out.println("Please select your class:");
        System.out.println("1. Warrior");
        System.out.println("2. Mage");
        System.out.println("3. Rogue");
        System.out.println("4. Archer");

        choice = (char) System.in.read(); // Get players choice of class



        switch(choice)
        {
        case '1': 
            System.out.println("You have chosen the Warrior class!");
            System.out.println("You're stats are as followed:");
            System.out.println("Str: 16");
            System.out.println("Int: 11");
            System.out.println("Chr: 14");
            System.out.println("Con: 15");
            System.out.println("Dex: 9");
            str = 16; 
            inte = 11;
            chr = 14;
            con = 15;
            dex = 9;
            break;

        case '2':
            System.out.println("You have chosen the Mage class!");
            System.out.println("You're stats are as followed:");
            System.out.println("Str: 16");
            System.out.println("Int: 11");
            System.out.println("Chr: 14");
            System.out.println("Con: 15");
            System.out.println("Dex: 9");
            str = 9; 
            inte = 16;
            chr = 14;
            con = 15;
            dex = 11;
            break;

        case '3':
            System.out.println("You have chosen the Rogue class!");
            System.out.println("You're stats are as followed:");
            System.out.println("Str: 16");
            System.out.println("Int: 11");
            System.out.println("Chr: 14");
            System.out.println("Con: 15");
            System.out.println("Dex: 9");
            str = 15; 
            inte = 11;
            chr = 14;
            con = 9;
            dex = 16;
            break;

        case '4':
            System.out.println("You have chosen the Archer class!");
            System.out.println("You're stats are as followed:");
            System.out.println("Str: 16");
            System.out.println("Int: 11");
            System.out.println("Chr: 14");
            System.out.println("Con: 15");
            System.out.println("Dex: 9");
            str = 9; 
            inte = 11;
            chr = 14;
            con = 15;
            dex = 16;
            break;

            default:
                System.out.println("Not a valid choice, please enter a digit 1-4");
                break caseChoice;

        }

}

    }
}

switch 中的默认语句的目的是将代码流带回类选择.我没有收到编译错误或运行时错误.当您选择除 1、2、3 或 4 之外的任何内容时.它说不是一个有效的选择,请输入一个数字 1-4",就像它假设的那样,但程序结束了.

The intent of the default statement in the switch is to bring the flow of code back to the class choice. I DO NOT receive a compile error or run time error. When you select anything besides 1, 2, 3, or 4. It says " Not a valid choice, please enter a digit 1-4" like it's suppose to, but the program ends.

我不能在开关中使用这样的标签吗?还是因为它在技术上超出了代码块而不起作用?

Am I not allowed to use a label like that in a switch? Or does it not work because it's technically outside the block of code?

推荐答案

我相信您在问题中描述的是某种 goto 功能,而 Java 中的标签不是这样工作的.

I believe that what you are describing in your problem is some kind of goto functionality and that is not how labels in Java works.

Java 不幸的是支持标签.这篇来自 Oracle 的文章中对此进行了描述.

Java unfortunately supports labels. This is described in this article from Oracle.

所以,基本上你可以有带标签的循环,你可以使用关键字continuebreak等来控制循环的流程.

So, basically you can have loops with labels and you can use keyword continue, break and so on to control the flow of the loop.

以下示例说明了如何使用带有 break 关键字的循环.当 break 被调用时,它会终止带标签的语句,即 someLabel 之后的语句.它不会返回到指定标签的位置执行.

The following sample illustrates how to use the loop with the break keyword. When break is invoked it terminates the labeled statement i.e. the statement following someLabel. It does NOT go back to execute where the label was specified.

someLabel:
    for (i = 0; i < 100; i++) {
        for (j = 0; j < 100; j++) {
            if (i % 20 == 0) {
                break someLabel;
            }
        }
    }

continue 关键字以相同的方式处理标签.当您调用例如continue someLabel;将继续外循环.

The continue keyword handles labels the same way. When you invoke e.g. continue someLabel; the outer loop will be continued.

作为 按照这个 SO-question 你也可以做这样的结构:

As per this SO-question you can also do constructs like this:

BlockSegment:
if (conditionIsTrue) {
    doSomeProcessing ();
    if (resultOfProcessingIsFalse()) break BlockSegment;
    otherwiseDoSomeMoreProcessing();
    // These lines get skipped if the break statement
    // above gets executed
}
// This is where you resume execution after the break
anotherStatement();

所以,基本上如果你 breakswitch 中的标签会发生什么情况,你会破坏整个语句(而不是跳转到语句的开头).

So, basically what happens if you break to a label in your switch you will break that entire statement (and not jump to the beginning of the statement).

您可以通过运行以下程序进一步测试标签.如果您输入quit",它会中断 while 循环,否则它只会中断开关.

You can test labels further by running the program below. It breaks the while-loop if you enter "quit", otherwise it simply breaks the switch.

public static void main(String... args) {
    programLoop:
    {
        while (true) {
            Scanner scanner = new Scanner(System.in);
            final String input = scanner.next();
            switch (input) {
                case "quit":
                    break programLoop; // breaks the while-loop
                default:
                    break; // break the switch
            }
            System.out.println("After the switch");
        }
    }
}

就个人而言,我需要一个非常特殊的情况才能推荐使用标签.我发现如果您重新排列代码以便不需要标签(例如将复杂代码分解为更小的函数),代码会更容易理解.

Personally, it would take a very special case in order for me to ever recommend using labels. I find that the code gets easier to follow if you instead rearrange your code so that labels are not needed (by e.g. break out complex code to smaller functions).

相关文章