带返回值的 Switch 语句——代码正确性

发布于 2024-09-05 18:35:21 字数 1699 浏览 4 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(18

两仪 2024-09-12 18:35:21

删除 break 语句。它们不是必需的,也许某些编译器会发出“无法访问的代码”警告。

Remove the break statements. They aren't needed and perhaps some compilers will issue "Unreachable code" warnings.

小草泠泠 2024-09-12 18:35:21

我会采取完全不同的策略。不要在方法/函数的中间返回。相反,只需将返回值放入局部变量中并在最后发送即可。

就我个人而言,我认为以下内容更具可读性:

String result = "";

switch (something) {
case 0:
  result = "blah";
  break;
case 1:
  result = "foo";
  break;
}

return result;

I would take a different tack entirely. Don't RETURN in the middle of the method/function. Instead, just put the return value in a local variable and send it at the end.

Personally, I find the following to be more readable:

String result = "";

switch (something) {
case 0:
  result = "blah";
  break;
case 1:
  result = "foo";
  break;
}

return result;
天涯离梦残月幽梦 2024-09-12 18:35:21

我会把它们删除。在我的书中,像这样的死代码应该被视为错误,因为它会让你重新考虑并问自己“我将如何执行该行?”

I would remove them. In my book, dead code like that should be considered errors because it makes you do a double-take and ask yourself "How would I ever execute that line?"

为你拒绝所有暧昧 2024-09-12 18:35:21

删除它们。从 case 语句中返回是惯用的,否则就是“无法访问的代码”噪音。

Remove them. It's idiomatic to return from case statements, and it's "unreachable code" noise otherwise.

多情出卖 2024-09-12 18:35:21

就我个人而言,我会删除退货并保留休息时间。我将使用 switch 语句为变量赋值。然后在 switch 语句之后返回该变量。

尽管这是一个有争议的观点,但我一直认为良好的设计和封装意味着一种进路和一种出路。保证逻辑要容易得多,并且您不会意外地错过基于函数的圈复杂度的清理代码。

一个例外:如果在函数开始时(在获取任何资源之前)检测到错误参数,那么提前返回是可以的。

Personally I would remove the returns and keep the breaks. I would use the switch statement to assign a value to a variable. Then return that variable after the switch statement.

Though this is an arguable point I've always felt that good design and encapsulation means one way in and one way out. It is much easier to guarantee the logic and you don't accidentally miss cleanup code based on the cyclomatic complexity of your function.

One exception: Returning early is okay if a bad parameter is detected at the beginning of a function--before any resources are acquired.

呆萌少年 2024-09-12 18:35:21

我通常会在没有它们的情况下编写代码。在我看来,死代码往往表明草率和/或缺乏理解。

当然,我也会考虑类似的事情:

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),您想要一个稀疏数组。您可以将其实现为树或地图,相当好(当然,开关在这种情况下仍然有效)。

I'd normally write the code without them. IMO, dead code tends to indicate sloppiness and/or lack of understanding.

Of course, I'd also consider something like:

char const *rets[] = {"blah", "foo", "bar"};

return rets[something];

Edit: even with the edited post, this general idea can work fine:

char const *rets[] = { "blah", "foo", "bar", "bar", "foo"};

if ((unsigned)something < 5)
    return rets[something]
return "foobar";

At some point, especially if the input values are sparse (e.g., 1, 100, 1000 and 10000), you want a sparse array instead. You can implement that as either a tree or a map reasonably well (though, of course, a switch still works in this case as well).

酒几许 2024-09-12 18:35:21

如果您有“查找”类型的代码,您可以将 switch-case 子句单独封装在一个方法中。

我在一个为了好玩而开发的“爱好”系统中有一些这样的内容:(

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 空间...)

我同意其他人的观点,即在大多数情况下,您应该避免在一个方法中出现多个返回,并且我确实认识到这个可能可以更好地实现为数组或其他东西。我刚刚发现 switch-case-return 与输入和输出之间具有 1-1 相关性的查找表非常容易匹配,就像上面的东西(角色扮演游戏中充满了它们,我确信它们存在于其他游戏中) “企业”也是如此):D

另一方面,如果 case 子句更复杂,或者 switch 语句之后发生了一些事情,我不建议在其中使用 return ,而是在 switch 中设置一个变量,以break结束,最后返回变量的值。

(…第三?一方面…你总是可以将开关重构为它自己的方法…我怀疑它会对性能产生影响,如果现代编译器甚至可以将其识别为可以内联的东西......)

If you have "lookup" type of code, you could package the switch-case clause in a method by itself.

I have a few of these in a "hobby" system I'm developing for fun:

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;
    }
}

(Yep. That's GURPS space...)

I agree with others that you should in most cases avoid more than one return in a method, and I do recognize that this one might have been better implemented as an array or something else. I just found switch-case-return to be a pretty easy match to a lookup table with a 1-1 correlation between input and output, like the above thing (role-playing games are full of them, I am sure they exist in other "businesses" as well) :D

On the other hand, if the case-clause is more complex, or something happens after the switch-statement, I wouldn't recommend using return in it, but rather set a variable in the switch, end it with a break, and return the value of the variable in the end.

(On the ... third? hand... you can always refactor a switch into its own method... I doubt it will have an effect on performance, and it wouldn't surprise me if modern compilers could even recognize it as something that could be inlined...)

天暗了我发光 2024-09-12 18:35:21

保留中断 - 如果/当您稍后编辑代码时,如果中断已经就位,那么您不太可能遇到麻烦。

话虽如此,许多人(包括我)认为从函数中间返回是不好的做法。理想情况下,函数应该有一个入口点和一个出口点。

Keep the breaks - you're less likely to run into trouble if/when you edit the code later if the breaks are already in place.

Having said that, it's considered by many (including me) to be bad practice to return from the middle of a function. Ideally a function should have one entry point and one exit point.

静赏你的温柔 2024-09-12 18:35:21

你觉得怎么样?把它们去掉就可以了吗?或者你会保留它们以增加“正确性”?

删除它们就可以了。使用return正是不应该使用break的场景。

What do you think? Is it fine to remove them? Or would you keep them for increased "correctness"?

It is fine to remove them. Using return is exactly the scenario where break should not be used.

ら栖息 2024-09-12 18:35:21

我想说删除它们并定义一个默认:分支。

I would say remove them and define a default: branch.

时光病人 2024-09-12 18:35:21

使用数组

arr[0] = "blah"
arr[1] = "foo"
arr[2] = "bar"

并执行 return arr[something]; 不是更好吗?

如果是一般实践,您应该将 break 语句保留在 switch 中。如果您将来不需要 return 语句,它会减少陷入下一个 case 的机会。

Wouldn't it be better to have an array with

arr[0] = "blah"
arr[1] = "foo"
arr[2] = "bar"

and do return arr[something];?

If it's about the practice in general, you should keep the break statements in the switch. In the event that you don't need return statements in the future, it lessens the chance it will fall through to the next case.

╰つ倒转 2024-09-12 18:35:21

对于“正确性”,单入口、单出口块是一个好主意。至少在我攻读计算机科学学位时是这样。所以我可能会声明一个变量,在 switch 中分配给它并在函数结束时返回一次

For "correctness", single entry, single exit blocks are a good idea. At least they were when I did my computer science degree. So I would probably declare a variable, assign to it in the switch and return once at the end of the function

捎一片雪花 2024-09-12 18:35:21

有趣的。大多数答案的共识似乎是,冗余的 break 语句是不必要的混乱。另一方面,我将 switch 中的 break 语句视为案例的“结束”。不以 break 结尾的 case 块往往会因为潜在的错误而跳出来。

我知道当有 return 而不是 break 时,情况并非如此,但这就是我的眼睛“读取” switch 中 case 块的方式,所以我个人会更喜欢每个 case 都与 break 配对。但许多编译器确实抱怨 return 后的 break 是多余/无法访问的,而且显然我似乎属于少数派。

因此,请摆脱 return 之后的 break

注意:所有这些都忽略了违反单次进入/退出规则是否是一个好主意。就目前而言,不幸的是,我的观点会根据情况而变化......

Interesting. The consensus from most of these answers seems to be that the redundant break statement is unnecessary clutter. On the other hand, I read the break statement in a switch as the 'closing' of a case. case blocks that don't end in a break tend to jump out at me as potential fall though bugs.

I know that that's not how it is when there's a return instead of a break, but that's how my eyes 'read' the case blocks in a switch, so I personally would prefer that each case be paired with a break. But many compilers do complain about the break after a return being superfluous/unreachable, and apparently I seem to be in the minority anyway.

So get rid of the break following a return.

NB: all of this is ignoring whether violating the single entry/exit rule is a good idea or not. As far as that goes, I have an opinion that unfortunately changes depending on the circumstances...

画中仙 2024-09-12 18:35:21

我说把它们去掉。如果你的代码难以阅读,以至于你需要在其中插入中断“为了安全起见”,你应该重新考虑你的编码风格:)

另外,我一直不喜欢在 switch 语句中混合中断和返回,而是混合使用中断和返回。坚持其中之一。

I say remove them. If your code is so unreadable that you need to stick breaks in there 'to be on the safe side', you should reconsider your coding style :)

Also I've always prefered not to mix breaks and returns in the switch statement, but rather stick with one of them.

所有深爱都是秘密 2024-09-12 18:35:21

我个人倾向于失去break。这种习惯的一个来源可能是来自为 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是多余的,因此应该消失 - 它们没有任何有用的目的(在语法上或 IMO 视觉上),只会使代码膨胀。

I personally tend to lose the breaks. Possibly one source of this habit is from programming window procedures for Windows apps:

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);
}

I personally find this approach a lot simpler, succinct and flexible than declaring a return variable set by each handler, then returning it at the end. Given this approach, the breaks are redundant and therefore should go - they serve no useful purpose (syntactically or IMO visually) and only bloat the code.

驱逐舰岛风号 2024-09-12 18:35:21

我认为 *break* 的存在是有目的的。这是为了保持编程的“意识形态”的活力。如果我们只是在没有逻辑连贯性的情况下“编程”我们的代码,也许您现在可以阅读,但明天再尝试。试着向你的老板解释一下。尝试在 Windows 3030 上运行它。

哎呀,这个想法非常简单:


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**;

/* 不过只是一个小问题。阅读以上内容时您喝了多少咖啡? IT有时破坏系统*/

I think the *break*s are there for a purpose. It is to keep the 'ideology' of programming alive. If we are to just 'program' our code without logical coherence perhaps it would be readable to you now, but try tomorrow. Try explaining it to your boss. Try running it on Windows 3030.

Bleah, the idea is very simple:


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**;

/* Just a minor question though. How much coffee have you had while reading the above? I.T. Breaks the system sometimes */

∞琼窗梦回ˉ 2024-09-12 18:35:21

在某一点退出代码。这为代码提供了更好的可读性。在其间添加 return 语句(多个退出)将使调试变得困难。

Exit code at one point. That provides better readability to code. Adding return statements (Multiple exits) in between will make debugging difficult .

暮倦 2024-09-12 18:35:21

只需定义变量并在 switch 语句的最后返回它,我们也可以通过设置变量=默认值来删除默认语句。

示例:

switch(someVariable)
{
case 'a':
 return a;
 break;
case 'b':
 return b;
 break;
default:
 return c;
}

解决方案:

    $result = c; //for default value
    switch(someVariable)
    {
    case 'a':
     $result = a;
     break;
    case 'b':
     $result = b;
     break;
    }
    return $result; //simply return $result
  • 这将导致您的退货单减少。

Simply define variable and return it at last of the switch statement and we can also remove default statement by setting variable= default value.

Ex:

switch(someVariable)
{
case 'a':
 return a;
 break;
case 'b':
 return b;
 break;
default:
 return c;
}

solution:

    $result = c; //for default value
    switch(someVariable)
    {
    case 'a':
     $result = a;
     break;
    case 'b':
     $result = b;
     break;
    }
    return $result; //simply return $result
  • This will lead to reduce your return statement.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文