在我的第一次代码评审中(不久前),有人告诉我,在所有switch语句中包含一个default子句是一种很好的实践。我最近想起了这个建议,但不记得理由是什么了。现在我听起来很奇怪。

是否有一个合理的理由总是包含默认语句? 这是语言依赖吗?我不记得当时我在用什么语言了——也许这适用于一些语言而不是其他语言?


当前回答

如果你知道switch语句只有一组严格定义的标签或值,那么就这样做,以覆盖基础,这样你总是会得到有效的结果。只需将默认值放在标签之上,从编程/逻辑上来说,它将是其他值的最佳处理程序。

switch(ResponseValue)
{
    default:
    case No:
        return false;
    case Yes;
        return true;
}

其他回答

No.

如果没有默认操作,那么上下文就很重要了。如果你只关心几个价值怎么办?

以读取游戏按键为例

switch(a)
{
   case 'w':
     // Move Up
     break;
   case 's':
     // Move Down
     break;
   case 'a':
     // Move Left
     break;
   case 'd':
     // Move Right
     break;
}

添加:

default: // Do nothing

只是浪费时间,毫无理由地增加了代码的复杂性。

我总是会使用默认子句,无论您使用哪种语言。

事情会出错,也确实会出错。价值观不会是你所期望的,等等。

不想包含默认子句意味着您确信自己知道可能的值集。如果你相信你知道这个可能值的集合,那么如果这个值在这个可能值的集合之外,你会想要知道它-这当然是一个错误。

这就是为什么你应该总是使用默认子句并抛出错误的原因,例如在Java中:

switch (myVar) {
   case 1: ......; break;
   case 2: ......; break;
   default: throw new RuntimeException("unreachable");
}

除了“unreachable”字符串之外,没有理由包含更多信息;如果它真的发生了,无论如何您都需要查看源代码和变量的值等,异常堆栈跟踪将包括该行号,因此不需要浪费时间在异常消息中写入更多文本。

如果你知道switch语句只有一组严格定义的标签或值,那么就这样做,以覆盖基础,这样你总是会得到有效的结果。只需将默认值放在标签之上,从编程/逻辑上来说,它将是其他值的最佳处理程序。

switch(ResponseValue)
{
    default:
    case No:
        return false;
    case Yes;
        return true;
}

至少在Java中它不是强制性的。根据JLS,它说最多可以出现一个违约情况。这意味着任何违约情况都是不可接受的。它有时也取决于你使用switch语句的上下文。例如,在Java中,下面的开关块不需要默认大小写

private static void switch1(String name) {
    switch (name) {
    case "Monday":
        System.out.println("Monday");
        break;
    case "Tuesday":
        System.out.println("Tuesday");
        break;
    }
}

但在下面的方法中,它期望返回一个String,默认大小写可以方便地避免编译错误

    private static String switch2(String name) {
    switch (name) {
    case "Monday":
        System.out.println("Monday");
        return name;

    case "Tuesday":
        System.out.println("Tuesday");
        return name;

    default:
        return name;
    }
}

虽然你可以在没有默认大小写的情况下避免上述方法的编译错误,只需要在最后添加一个return语句,但是提供默认大小写会使它更具可读性。

您应该有一个默认值来捕捉传入的非预期值。

然而,我不同意Adrian Smith关于默认的错误消息应该是完全没有意义的。可能会有一个你没有预见到的未处理的情况(这是一点),你的用户最终会看到,像“无法到达”这样的消息是完全没有意义的,在这种情况下对任何人都没有帮助。

举个例子,你有多少次经历过毫无意义的蓝皮书?或者致命异常@ 0x352FBB3C32342?