Java Newb: возвращаемый параметр не переназначается после рекурсивного цикла - PullRequest
1 голос
/ 29 апреля 2020
    static String ask(String question) {

        String Answer = JOptionPane.showInputDialog(question);
        Answer = Answer.toUpperCase();

        System.out.println("User, " + counter +"," + Answer); // for debugging purposes
        counter += 1; // for debugging purposes

        switch (Answer){

        case "A":
            return(Answer);
        case "B":
            return(Answer);
        case "C":
            return(Answer);
        case "D":
            return(Answer);
        case "E":
            return(Answer);
        default:
            JOptionPane.showMessageDialog(null, "Invalid Answer.  Please Enter A,B,C,D,or E:");
            ask(question);
            // when invalid option entered, we loop back to beginning of method - Answer not being reassigned

        }
        return(Answer);  // I don't need this, Java won't let me run without it

после ввода нескольких недопустимых записей, возвращенный параметр не переназначается с допустимой записью. пример вывода:

User, 1,U
User, 2,I
User, 3,O
User, 4,P
User, 5,M
User, 6,A
User Answer:U
CorrectAnser:A
false

Как видите, «U» была первой записью, а последняя - «A» - записью, которая вышла из l oop. Хотя «U» - это то, что возвращается, а не «A». Не можете понять, почему?

1 Ответ

1 голос
/ 29 апреля 2020

Как сказал Ивар в комментариях, вы не возвращаете ответ в части default вашего оператора switch. Вы должны сказать return ask(question вместо того, чтобы просто позвонить ask(question). Тогда часть return answer внизу будет ненужной. См. Код ниже (я также немного изменил его, чтобы он выглядел более эстетично).

Вы должны понимать, что при повторном вызове метода оператор return только возвращается из этого последнего вызова метода. Поэтому в исходном вызове метода результат ask(question) игнорируется (это практически похоже на вызов метода void). Операторы возврата не возвращаются к первому методу в стеке. Вот почему вам нужен возврат по умолчанию.

static String ask(String question) {

        String answer = JOptionPane.showInputDialog(question).toUpperCase();

        System.out.println("User, " + counter +"," + answer); // for debugging purposes
        counter += 1; // for debugging purposes

        switch (answer) {
        case "A":
        case "B":
        case "C":
        case "D":
        case "E":
            return answer;
        default:
            JOptionPane.showMessageDialog(null, "Invalid Answer.  Please Enter A,B,C,D,or E:");
            return ask(question);
            // when invalid option entered, call method again (btw, you're not looping back, it's just recursion)
        }
}

Превратился в al oop, это будет:

static String ask(String question) {
  String result = question;
  do {
    String answer = JOptionPane.showInputDialog(question).toUpperCase();
    switch (answer) {
        case "A":
        case "B":
        case "C":
        case "D":
        case "E":
            result = answer;
            break;
        default:
            JOptionPane.showMessageDialog(null, "Invalid Answer.  Please Enter A,B,C,D,or E:");
        }
  } while (result == question); //I know, I know, I'm using "==". But it should be fine because question is assigned to it at the start
  return result;

Представьте, что у вас есть функция, которая принимает 2 строки, хэши они оба, и затем возвращает true, если код ha sh первого больше, чем у второго.

public boolean compareHashCodes(String s1, String s2) {
  int hash1 = hash(s1), hash2 = hash(s2);
  hash(s1);
  return hash1 > hash2;
}

public int hash(String s) {
  return s.hashCode(); //or something else
}

Как вы можете видеть, когда вы вызываете метод hash в первый раз и возвращает int, это не значит, что compareHashCodes также немедленно возвращает int. Он просто сохраняет это int в переменной hash1. То же самое происходит во второй раз, когда вы вводите хэш-код в hash2. В третий раз значение hash(s1) игнорируется, а не возвращается, потому что возвращать целые числа из метода, который должен возвращать логические значения, не имеет смысла. Только когда достигается окончательное утверждение return hash1 > hash2, метод compareHashCodes действительно возвращается.

...