Java 环路中断或返回的实践

Java 环路中断或返回的实践,java,loops,return,conditional-statements,break,Java,Loops,Return,Conditional Statements,Break,背景:我正在下国际象棋。它几乎完全可以工作,只是没有检查将死,但我正在改进一些代码以提高可读性等。 现在,我正在重新编码一种方法,我必须检查从任何一块到电路板上另一个位置的路径。如果有块阻塞路径,则返回true;如果没有块,则返回false。 注意:我不需要检查最后一个位置的位置,因为我的游戏将进行检查以确保您没有占据您试图移动到的位置 还要注意的是,我已经研究了这个问题,我发现主要在这里达成的共识是,打破僵局是正确的解决方案。这比让一个布尔变量在循环外部初始化、设置为true或false并在该

背景:我正在下国际象棋。它几乎完全可以工作,只是没有检查将死,但我正在改进一些代码以提高可读性等。
现在,我正在重新编码一种方法,我必须检查从任何一块到电路板上另一个位置的路径。如果有块阻塞路径,则返回true;如果没有块,则返回false。
注意:我不需要检查最后一个位置的位置,因为我的游戏将进行检查以确保您没有占据您试图移动到的位置

还要注意的是,我已经研究了这个问题,我发现主要在这里达成的共识是,打破僵局是正确的解决方案。这比让一个布尔变量在循环外部初始化、设置为true或false并在该值上中断循环更可取。然而,我的循环中有两个条件可能使我的代码返回true或false,所以我不能完全这样做

现行代码

问题: 这似乎是一种可能令人困惑的混合。因此,在我的情况下,这仍然是优于此代码的首选方法:

boolean clear;

    while(true) {
        atx += xdiff; 
        aty += ydiff;

        if(atx == endx && aty == endy) {
            clear = true;
            break;
        }

        if(board[atx][aty].getType() != ' ') {
            clear = false;
            break;
        }
    }

    return clear;

大多数情况下,我会说这是一件主观的事情


上一个代码示例的一个客观优势是,它为您提供了一个退出方法的单点,这对于调试通常很有用。我曾经和一个做军事软件的家伙一起工作过,他说这是他们必须努力的一个要求:一个方法必须只有一个出口点。他声称这是一个健壮性/可靠性/可维护性的东西。我只是喜欢简单的“这里就是它离开的地方”的东西。

我更喜欢在这类循环中使用return,因为我认为中断只是一种浪费。 在方法的末尾保留一个return语句,并在if语句中使用两个常规的return语句,它们将返回true或false

最后我还记得我编写了类似的代码,因为我的方法的返回类型是void,所以我可以简单地使用:

return;
它将退出循环和方法。

而不是
while(true)
,您可以尝试在
while
循环中处理您的实际情况,而不需要额外的
break
语句:

public boolean isPathClear(Location l1, Location l2) {
    int atx =  l1.getX(), aty =  l1.getY();
    int endx = l2.getX(), enxy = l2.getY();

    int xdiff = Integer.signum(endx - atx);
    int ydiff = Integer.signum(endy - aty);

    do{
        atx += xdiff;
        aty += ydiff;
    } while(!(atx == endx && aty == endy) && board[atx][aty].getType() == ' ');

    return atx == endx && aty == endy;
}

使用返回语句。这样做的目的是保持它的可读性和可维护性。只要不要在那些if语句中进行不同的方法调用,您就会没事了

阅读Bruce Eckel的这篇文章:


使用return语句的另一个好处是,其他程序员不太可能出现并修改您的局部变量,从而导致返回不正确的值。

如果您想使用
break
执行此操作,则这并不重要-但我更喜欢这样:

boolean notObstructed = true;
while(notObstructed) {
    atx += xdiff; 
    aty += ydiff;
    if(atx == endx && aty == endy)
        break;
    if(board[atx][aty].getType() != ' ')
        notObstructed = false;
}
return notObstructed;

这样,只有一个返回语句的值是根据
while
循环和
if
语句配置的。

我根本不会使用
while(true)
,但我认为我在这方面是少数。:-)你能展示一下你的整个方法吗?代码应该做什么?这里有一个关于整个主题的很好的讨论:我认为目标是一致性。我会做第一个或最后一个例子(第一个,我自己),但不会做第二个。无论哪种方式,保持一致性都更容易让读者理解。要想获得具有挑战性的心智发展,请选择最短、可读性最好的方式。这可能意味着:回报。这样的讨论浪费了你的时间和精力去推动你去生产一些好的和智能的东西。仅仅因为一个需求是军用软件,并不意味着这个需求是一个好的需求。或者它甚至是有意义的。@Dodd10x:这里没有争论。在这种情况下,我会说这有很好的理由,但是。@Dodd10x,没有人说这是一个好的要求。海报简单地指出,在这种情况下,一种风格可能有一个优势。@MatthewC-TJ后来扩展了他的答案,但我的观点只是说军方要求它不能使它正确。事实上,许多军事合同仍然需要瀑布式开发模型——我认为stackoverflow上的大多数人都会反对这一点?运算符,尽管该代码看起来非常漂亮。它无法工作的原因是xdiff和ydiff可能为0。如果沿x轴或y轴移动,而不是沿对角线移动,则其中一个将为0。对于这种情况,最短的代码是另外两条语句,如
intxdiff=atx>0?0:atx
此外,还可以执行int-xdiff=atx==endx?0:(atx>endx?1:-1);在一条语句中,但它确实开始显得复杂。此外,我还调整了while循环以处理while()中的两个条件。此外,我怀疑无论您如何实现这一点,您都会希望将增量步骤更改为'atx+=atx==endx?0:xdiff'(与y类似)来处理x和y不同时停止的情况。您能详细说明对增量的更改吗?
public boolean isPathClear(Location l1, Location l2) {
    int atx =  l1.getX(), aty =  l1.getY();
    int endx = l2.getX(), enxy = l2.getY();

    int xdiff = Integer.signum(endx - atx);
    int ydiff = Integer.signum(endy - aty);

    do{
        atx += xdiff;
        aty += ydiff;
    } while(!(atx == endx && aty == endy) && board[atx][aty].getType() == ' ');

    return atx == endx && aty == endy;
}
boolean notObstructed = true;
while(notObstructed) {
    atx += xdiff; 
    aty += ydiff;
    if(atx == endx && aty == endy)
        break;
    if(board[atx][aty].getType() != ' ')
        notObstructed = false;
}
return notObstructed;