【问题标题】:Why can't I write a return statement inside a loop?为什么我不能在循环中编写返回语句?
【发布时间】:2019-03-01 08:13:18
【问题描述】:

我正在编写一个函数,它给了我最大的因子,它是一个数的质数。例如,数字 12 会给我 3。我的初始代码是:

public static int getLargestPrime(int number) {
        if (number < 2) {
            return -1;
        }

            for (int num = 2; num <= number; num++) {
                int mod = number % num;
                if (mod == 0) {
                    int div = number / num;
                    if (div == 1) {
                        return number;
                    } else {
                        number = div;
                        num = 1;
                    }
                }
            }
    }

但我不断收到缺少返回语句的错误,所以我添加了一个:

public static int getLargestPrime(int number) {

        if (number < 2) {
            return -1;
        }

            for (int num = 2; num <= number; num++) {
                int mod = number % num;
                if (mod == 0) {
                    int div = number / num;
                    if (div == 1) {
                        return number;
                    } else {
                        number = div;
                        num = 1;
                    }
                }
            }
            return number;
    }

现在是正确的,但我不太明白它背后的逻辑。我已经读到在某些情况下循环不会执行,因此即使我的循环没有执行,我也需要返回一些东西,但是我想不出我的循环不会执行的任何情况。从字面上看,任何 2 或以上的东西都会触发循环,任何小于 2 的东西都将返回 -1。所以我的问题是在什么情况下循环不会执行?还有,for循环后面的return语句真的没有意义,有没有更好的办法解决缺少的return语句?

【问题讨论】:

  • 你可以,但是你需要为所有场景的返回语句,这也意味着当迭代不循环时。
  • 我建议添加新变量,例如 returnValue ,您将在需要的每个地方设置它,并且在此函数末尾的所有循环都返回此值
  • 例如,你永远不会进入 if for "div == 1" 的理论案例。如果这种情况以某种方式发生,您将永远不会返回,因此需要在 for 循环之后返回。这种情况可能永远不会出现,但编译器不知道,所以这就是你在 for 循环之后返回语句的原因。你也可以只抛出一个专门的异常而不是返回数字。
  • 如果你在 else case 或者在循环之外,你应该返回一些 int i。返回 0;
  • 如果您确定在循环中的某个时间会返回一个值,请在方法底部添加throw new AssertionError("Never ending here");。这将使编译器满意并且没有效果(除非您的假设中断)。

标签: java


【解决方案1】:

在您的初始代码中:

if (div == 1) {
    return number;
} else {
    number = div;
    num = 1;
}
                    }

如果你总是有 false,你将永远无法达到 return 语句。 编译器不预测它是否真的会发生,因此它需要在 if 和 else 块中都使用 return 语句。所以它实际上与for循环无关。

【讨论】:

    【解决方案2】:

    两个建议 1.最好不要改变你传递的参数(在这种情况下是数字变量) 2. 尽可能少的返回语句。

    在您的情况下,您可以在 for-lopp 之外声明另一个变量 tempNumber 并分配“数字”。在您返回的 if 条件下,您“中断”。返回函数末尾的数字。这样总是返回数字

    public static int getLargestPrime(int number) {
    
        if (number < 2) {
            return -1;
        }
    
        int tempNumber = number;
        for (int num = 2; num <= tempNumber; num++) {
            int mod = tempNumber % num;
            if (mod == 0) {
                int div = tempNumber / num;
                if (div == 1) {
                    break;
                } else {
                    tempNumber = div;
                    num = 1;
                }
            }
        }
        return tempNumber;
    
    }
    

    【讨论】:

      【解决方案3】:

      https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.14

      Java 编译器不会在循环中验证您的代码,因此您需要将 return 语句放在所有的 fork 中。 覆盖测试会警告你,因为你有一个无法访问的代码,所以你需要重新规划你的代码。

      注意:您需要检查您的 prime test 直到或等于 Math.sqrt(number),如果大于此 sqrt 而没有分隔符,您可以打破循环并返回 number

      【讨论】:

        【解决方案4】:

        我想不出我的循环不会执行的任何情况

        必须以有效、明确定义的方式编写方法。将其视为帮助编译器的一种形式。

        在编译时检查return 语句的存在。如果编译器发现一个可能的执行分支没有以有效的返回语句(或显式抛出的异常)结束,它会遇到错误。 Read more.

        甚至...

        int method() {
            if (true)
                return 1;
        }
        

        ... 使用

        将无法编译

        This method must return a result of type int

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-10-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多