Hen*_*rek 73 java if-statement
自动对我的代码进行评分的程序正在为不执行任何代码的 else-if 对接我的“样式点”。它说它可能会导致错误,但我认为它不会。
我不确定如何更改它以使其仍然有效但不违反规则。为什么要做这种糟糕的形式?我认为我写的任何其他方式都会让读者更难理解。应该怎么写呢?
if (! seesWater(LEFT))
{
turn(LEFT);
}
else if (! seesWater(AHEAD));
else if (! seesWater(RIGHT))
{
turn(RIGHT);
}
else
{
turn180();
}
Run Code Online (Sandbox Code Playgroud)
else-if 在那里但什么都不做的原因是因为我希望代码执行的优先级:
if (! seesWater(AHEAD)),那么我根本不希望其余条件运行,因为它们无关紧要。
J.B*_*kus 140
谁说这是“糟糕的风格”?
要问的相关问题是,这比替代方案更清楚吗?在你的具体情况下,我会说它是。代码清楚地表达了 4 个选项之间的选择,其中一个是“什么都不做”。
我要做的唯一改变是用一对空的大括号替换那个相当微不足道的分号,可能用注释来表明这不是错误。
if (! seesWater(LEFT)) {
turn(LEFT);
}
else if (! seesWater(AHEAD)) {
// nothing required
}
else if (! seesWater(RIGHT)) {
turn(RIGHT);
}
else {
turn180();
}
Run Code Online (Sandbox Code Playgroud)
这并不是支持“空条款”作为一种普遍可接受的风格;只是认为案件应该根据案情进行辩论,而不是根据某些必须遵守的规则。这是培养良好品味的问题,品味的判断是针对人类的,而不是无意识的自动机。
use*_*460 45
如果这是您想要的逻辑,那么您的代码就没有问题。在代码样式方面,我同意其他用户的意见。在我看来,这样的事情会更清楚:
if (! seesWater(LEFT))
{
turn(LEFT);
}
else if (! seesWater(AHEAD))
{
//Do nothing
}
else if (! seesWater(RIGHT))
{
turn(RIGHT);
}
else
{
turn180();
}
Run Code Online (Sandbox Code Playgroud)
但是通过优先左转而不是向前移动(通过什么都不做),运动可能会以循环结束:
如果你想让运动“什么都不做”,但避免像这样进入水域:
您可能希望将逻辑更改为如下所示:
if (! seesWater(AHEAD))
{
//Do nothing. Keep moving
}
else if (! seesWater(LEFT))
{
turn(LEFT);
}
else if (! seesWater(RIGHT))
{
turn(RIGHT);
}
else
{
turn180();
}
Run Code Online (Sandbox Code Playgroud)
Swe*_*per 26
您可以反转! seesWater(AHEAD)条件。然后您可以将其else子句中的代码移动到其if子句中:
if (! seesWater(LEFT))
{
turn(LEFT);
}
else if (seesWater(AHEAD))
{
if (! seesWater(RIGHT))
{
turn(RIGHT);
}
else
{
turn180();
}
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*eve 13
我认为您可以决定根本不更改代码的逻辑。我认为没有理由避免空if或else if块,如果这会导致您的代码最易读且逻辑最易理解。您通常可以重写您的代码,使其不包含空代码块,但仍然可以理解。但如果没有,我说这很好。
不过有一件事……我不喜欢使用 a;来表示空代码块的风格。这真的很容易错过,通常不会看到,所以它会让读者感到困惑。我建议用;一组空的花括号替换。您还可以在空卷曲中添加注释,以明确表示该代码块为空,即// In this case, we don't want to do anything.
rta*_*aft 13
对于这个特定的代码示例,我不认为逻辑是准确的,并且不直观。如果前方有水,您似乎想转弯……但是在那里左转会让人感到困惑,并且可能是一个错误。最终,我将空洞的逻辑视为双重否定,“如果前方没有水,则什么都不做”,并且双重否定也令人不悦。
if (seesWater(AHEAD))
{
if (! seesWater(LEFT))
{
turn(LEFT);
}
else if (! seesWater(RIGHT))
{
turn(RIGHT);
}
else
{
turn180();
}
}
Run Code Online (Sandbox Code Playgroud)
这是最有意义的,因为附加逻辑基于前方是否有水。如果前方有水,如果您想将动作移动到另一个功能,它也会更容易。
use*_*366 13
我发现if(!condition)语句中的否定逻辑难以阅读且令人费解,与 if-else-else-else 结合使用时更是如此。我更喜欢正逻辑seesLand()而不是!seesWater.
您可以修改 turn() 函数,这样turn(AHEAD)它什么都不turn(BACK)做,而是进行 180 度转弯,而不需要为此单独使用一个函数。
然后你可以把它改写成。
List<Direction> directions = new ArrayList(LEFT, FORWARD, RIGHT, BACK);
for (Direction d: directions) {
if(seesLand(d) {
turn(d);
return;
}
Run Code Online (Sandbox Code Playgroud)
一个好处是,这更加概括。您可以简单地通过定义另一个数组来创建不同的移动策略,您可以在其中根据需要对方向进行排序,并将它们输入到此函数中以检查并按所选顺序转动。
Fra*_*ins 10
你用这样的东西做的是把它变成一种说话的方法,最好把它分开。
选项1:
private turnTowardsGround(){
if(! seesWater(AHEAD){
return;
}
if (! seesWater(LEFT))
{
turn(LEFT);
return;
}
if (! seesWater(RIGHT))
{
turn(RIGHT);
return;
}
turn180();
}
Run Code Online (Sandbox Code Playgroud)
选项 2:
private determineMoveDirection(){
if(! seesWater(AHEAD){
return AHEAD;
}
if (! seesWater(LEFT))
{
return LEFT
}
if (! seesWater(RIGHT))
{
return RIGHT
}
return BACK;
}
Run Code Online (Sandbox Code Playgroud)
然后使用选项 2,如:
Direction directionToMove = determineMoveDirection();
turn(directionToMove);
Run Code Online (Sandbox Code Playgroud)
为什么?因为方法名称使代码的意图清晰。并且早期返回退出允许快速阅读,我们不需要阅读整个 if-else 代码以确保一旦一个案例适用就不会发生其他事情。另外,在选项 2 的情况下,您有明确的关注点分离(找出移动到的位置与实际转向的位置),这对模块化非常有用,并且在这种情况下还允许在一个地方记录您要去的最终决定转,例如。
此外,最好不要取消检查,但会有一个“seesLand”或“seesAccessibleFieldType”方法。解析非否定语句在心理上更容易/更快,并且它使您更清楚您实际在寻找什么(即地块,冰块,......)。
为什么空 if 子句是糟糕的风格?因为它是一种“退出” if 块的非明显方式。它跳过后续的 else-if,更重要的是跳过最后的 else,它在多条件块中最终作为“默认”操作。
对我来说,这里有两个主要问题:
do_nothing而不是全部我在查看这样的代码时会问的第一个问题是为什么 do_nothing 选项(! seesWater(AHEAD))不是我们检查的第一件事?是什么让! seesWater(LEFT)我们检查的第一件事是什么?我希望看到关于为什么这个顺序很重要的评论,因为 if 似乎并不明显是排他的(可以在多个方向看到水)。
我要问的第二个问题是在什么情况下我们希望最终出现在包罗万象的else声明中。目前turn180()是“默认”,但如果由于某种原因环顾四周失败,我觉得回到你来的方式并不是很默认的行为。
小智 7
我来自 C,和 MISRA 一起生活,但对我来说,带分号的“if”是不好的风格,无论是否有“else”。原因是人们通常不会在那里放分号,除非它是一个错字。考虑一下:
if (! seesWater(AHEAD));
{
stayDry();
}
Run Code Online (Sandbox Code Playgroud)
在这里,阅读代码的人会认为,如果您没有看到前方有水,您只会使用stayDry()——您必须仔细观察才能看到它实际上会被无条件地调用。更好的是,如果您不想在这种情况下做任何事情,则使用大括号和注释:
if (! seesWater(AHEAD))
{
/* don't need to do anything here */
}
Run Code Online (Sandbox Code Playgroud)
事实上,应该始终将大括号放在“if”、“else”等的主体周围,即使子句是单个 turn() 调用,也应该使用大括号!我有时会发现像这样的代码
if (! seesWater(AHEAD))
stayDry();
Run Code Online (Sandbox Code Playgroud)
那么稍后会有人加入并添加其他内容:
if (! seesWater(AHEAD))
stayDry();
doSomethingElse();
Run Code Online (Sandbox Code Playgroud)
当然,无论您是否看到水,其他东西都会完成,这不是第二个编码员的意图。您可能认为没有人会犯如此明显的错误,但他们确实会犯。
样式检查器报告样式不佳的原因是实施样式检查器的人认为它是糟糕的样式。
你必须问他们为什么,他们的回答可能有价值,也可能没有。
任何需要人类智能的自动检查器都应该谨慎对待。有时它们会产生有用的输出,有时则不会。如果这样的检查员正在评估一个人的工作,那是非常不幸的,如果该评估有后果,那将是非常不幸的。
| 归档时间: |
|
| 查看次数: |
7591 次 |
| 最近记录: |