带有返回的切换语句 - 代码正确性
-
28-09-2019 - |
题
假设我在C中具有大约此结构的代码:
switch (something)
{
case 0:
return "blah";
break;
case 1:
case 4:
return "foo";
break;
case 2:
case 3:
return "bar";
break;
default:
return "foobar";
break;
}
现在,显然,“断裂”是不需要正确运行的,但是如果我不把它们放在我身边,那就看起来像是不好的练习。
你怎么看?删除它们可以吗?还是您会保留它们以提高“正确性”?
解决方案
去除那个 break
语句。它们不需要,也许有些编译器会发出 “无法达到的代码” 警告。
其他提示
我会完全做一个不同的钉子。不要在方法/函数中间返回。相反,只需将返回值放入本地变量中,然后将其发送到最后即可。
就个人而言,我发现以下内容更可读性:
String result = "";
switch (something) {
case 0:
result = "blah";
break;
case 1:
result = "foo";
break;
}
return result;
我个人会删除回报并保留休息。我将使用Switch语句将值分配给变量。然后在开关语句之后返回该变量。
尽管这是一个有争议的观点,但我一直认为良好的设计和封装意味着一种方法,并且是一种出路。确保逻辑的保证要容易得多,并且您不会根据功能的循环复杂性而意外地错过清理代码。
一个例外:如果在获取任何资源之前,在函数开始时检测到一个不良的参数,则可以提早返回。
保持休息时间 - 如果/稍后编辑代码已经到位,您就不太可能遇到麻烦。
话虽如此,许多人(包括我)认为从功能中间回来是不好的做法。理想情况下,功能应具有一个入口点和一个出口点。
删除它们。从中返回是惯用的 case
陈述,否则是“无法到达的代码”噪声。
我会删除它们。在我的书中,像这样的死密码应该被视为错误,因为它会使您进行双重操作,并问自己“我将如何执行该行?”
我通常在没有它们的情况下编写代码。 IMO,死亡代码倾向于表明不理解和/或缺乏理解。
当然,我也会考虑这样的东西:
char const *rets[] = {"blah", "foo", "bar"};
return rets[something];
编辑:即使有编辑的帖子,这个总体想法也可以正常工作:
char const *rets[] = { "blah", "foo", "bar", "bar", "foo"};
if ((unsigned)something < 5)
return rets[something]
return "foobar";
在某个时候,尤其是如果输入值稀疏(例如1、100、1000和10000),则需要一个稀疏的数组。您可以很好地将其作为树或地图实现(尽管当然,在这种情况下,开关仍然可以正常工作)。
我会说删除它们并定义默认设置:分支。
拥有一个数组会更好
arr[0] = "blah"
arr[1] = "foo"
arr[2] = "bar"
并做 return arr[something];
?
如果这是关于实践的,那么您应该保留 break
开关中的语句。如果您不需要 return
陈述将来,它减少了它将落入下一个的机会 case
.
对于“正确性”,单个条目,单个出口块是一个好主意。至少是我获得计算机科学学位的时候。因此,我可能会声明一个变量,在交换机中分配给它,然后在函数末尾返回一次
你怎么看?删除它们可以吗?还是您会保留它们以提高“正确性”?
可以删除它们是可以的。使用 return
是 确切地 场景 break
不应使用。
有趣的。大多数这些答案的共识似乎是多余的 break
声明是不必要的混乱。另一方面,我读了 break
在开关中说明案件的“关闭”。 case
没有结束的块 break
当潜在的漏洞时,往往会跳出我。
我知道那不是当 return
代替 break
, ,但这就是我的眼睛“阅读”案例在开关中阻碍的方式,所以我个人更喜欢每个人 case
与 break
. 。但是许多编译器确实抱怨 break
之后 return
是多余的/无法实现的,显然我似乎是少数派。
所以摆脱 break
遵循 return
.
NB:所有这些都忽略了违反单个条目/退出规则是否是一个好主意。就此而言,我有一个观点,不幸的是,根据情况的不同。
我说删除它们。如果您的代码不可读取,以至于您需要在“安全方面”中休息一下,则应重新考虑您的编码样式:)
另外,我一直更喜欢不混合断裂和返回在开关语句中,而是粘在其中之一中。
我个人倾向于失去 break
s。此习惯的一个来源可能是来自Windows应用程序的编程窗口程序:
LRESULT WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_SIZE:
return sizeHandler (...);
case WM_DESTROY:
return destroyHandler (...);
...
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
我个人发现这种方法比宣布每个处理程序设置的返回变量要简单,简洁和灵活,然后在最后返回。鉴于这种方法 break
s是多余的,因此应该走 - 它们没有有用的目的(句法或视觉上的IMO),只膨胀代码。
我觉得 *休息*S有目的。这是为了使编程的“意识形态”保持活力。如果我们只是在没有逻辑连贯性的情况下“编程”代码,也许现在可以阅读,但明天尝试。尝试向老板解释。尝试在Windows 3030上运行它。
Bleah,这个想法非常简单:
Switch ( Algorithm )
{
case 1:
{
Call_911;
Jump;
}**break**;
case 2:
{
Call Samantha_28;
Forget;
}**break**;
case 3:
{
Call it_a_day;
}**break**;
Return thinkAboutIt?1:return 0;
void Samantha_28(int oBed)
{
LONG way_from_right;
SHORT Forget_is_my_job;
LONG JMP_is_for_assembly;
LONG assembly_I_work_for_cops;
BOOL allOfTheAbove;
int Elligence_says_anyways_thinkAboutIt_**break**_if_we_code_like_this_we_d_be_monkeys;
}
// Sometimes Programming is supposed to convey the meaning and the essence of the task at hand. It is // there to serve a purpose and to keep it alive. While you are not looking, your program is doing // its thing. Do you trust it?
// This is how you can...
// ----------
// **Break**; Please, take a **Break**;
/*只是一个小问题。您在阅读上述咖啡时喝了多少咖啡?它 休息 系统有时 */
一度退出代码。这为代码提供了更好的可读性。在两者之间添加返回语句(多个出口)将使调试变得困难。
如果您具有“查找”类型的代码,则可以单独将Switch-sase子句打包。
我为了娱乐而开发的“爱好”系统中有一些:
private int basePerCapitaIncomeRaw(int tl) {
switch (tl) {
case 0: return 7500;
case 1: return 7800;
case 2: return 8100;
case 3: return 8400;
case 4: return 9600;
case 5: return 13000;
case 6: return 19000;
case 7: return 25000;
case 8: return 31000;
case 9: return 43000;
case 10: return 67000;
case 11: return 97000;
default: return 130000;
}
}
(是的。那是gurps空间...)
我同意其他人的观点,您应该在大多数情况下避免使用一种以上的返回,并且我确实认识到,这可能已经更好地实现为数组或其他东西。我刚刚发现开关案例返回是与在输入和输出之间具有1-1相关性的查找表的非常简单的匹配,就像上面的东西(角色扮演游戏中充满了它们,我敢肯定它们存在于其他方面“企业”也):D
另一方面,如果案例子句更为复杂,或者在开关说话之后发生了一些事情,我不建议在其中使用返回,而是在开关中设置一个变量,然后折断并返回最终变量的值。
(在...第三?手...您总是可以将开关重构为自己的方法...我怀疑它会对性能产生影响,如果现代编译器甚至可以将其识别为可能会嵌入的东西...)