【问题标题】:Is using "default" case in a switch statement a good habit? [closed]在 switch 语句中使用“默认”大小写是一个好习惯吗? [关闭]
【发布时间】:2011-03-06 15:50:19
【问题描述】:


当我使用开关时(在这种情况下是 Java),如果需要,我通常使用默认情况。我的一位老师告诉我,当他以前用 Pascal 编程时,这种情况并不存在。他说如果 Pascal 中不存在它,那么它不应该是好用的东西。

我的问题是:

  • 使用默认大小写有错吗?
  • 它在内部是如何工作的?

提前致谢。

【问题讨论】:

  • 要么你的老师在开玩笑,要么你需要一个新老师。
  • Pascal 中不存在某些东西并不意味着它不好。我的意思是,Pascal 也没有垃圾收集。这并没有坏处。
  • @GoranJovic 虽然从广义上讲,正如您所说的那样,这是真的,但这里的情况(双关语!)略有不同:设计决策(在 Pascal 中)从特定功能中省略了一些细节,以及其他容易实现的细节。 [无论如何,Pascal 确实有 default/else。]

标签: java coding-style switch-statement pascal


【解决方案1】:

我认为不使用它是一个坏习惯。

  • 如果您认为默认情况永远不会发生,请抛出异常以确保
    • 如果您切换枚举,则可能有人添加了另一个值
    • 如果切换一个整数,总是有可能发现意外的值
  • 因为默认情况总是在您最不期望的时候发生
  • 据我所知,Pascal 中有类似的东西

编辑:

这是帕斯卡,只是为了证明你的老师错了

case place of
  1: writeln('Champion');
  2: writeln('First runner-up');
  3: writeln('Second runner-up'); 
  else writeln('Work hard next time!'); 
end;

【讨论】:

  • +1 用于代码示例。即使没有它的语法,也可以使用嵌套的 if-then-else 语句来编写它。所以,这绝对可以用 Pascal 编写。
  • @Arian - “因为默认情况总是在你最不期望的时候发生” - 当轻微损坏的构建文件将以前版本的代码放入构建(否则正确)代码。以前的版本没有默认情况;正确的版本扩展了案例陈述。发现这是一项重大任务 - 它构建良好,但在重建系统中发现错误需要数天和大量工时。
  • 谢谢。我希望他是在开玩笑,否则我会很难相信他告诉我的任何事情......我必须自己检查一切。
  • @Chris:我可以想象这很难找到......我仍然想知道我们可以从中学到什么。
  • 实际上,在最初的 Pascal 中并没有这样的东西。它是后来在标准化阶段(1983 年左右)添加的。可以看出,Borland 使用“ELSE”,Apple 和 ISO pascal 使用“OTHERWISE”
【解决方案2】:

使用默认大小写始终是一个好习惯。我什至在打开枚举时使用它。如果枚举有 3 个值,我有 3 个 case 语句和一个抛出 AssertionError 的 case 语句。

这很好,因为如果扩展枚举,可以确保很快检测到与缺少 switch 语句中的新值相关的错误。

【讨论】:

  • 通常不应该在 java 中抛出错误,因为错误表明存在无法(也不应该)恢复的大问题。许多人使用 IllegalArgumentException 来表示意外的默认情况。
  • 我认为 IllegalArgumentException 表示无效的函数参数。就我而言,AssertionError 恕我直言是个好主意,因为它表明覆盖所有枚举的断言是错误的。
  • 我完全明白你的意思,我对IllegalArgumentExceptions 也不满意。但是许多(大多数?)人使用catch (Exception e),如果他们希望他们的程序即使发生意外情况也能继续,这样他们就不会捕获 AssertionErrors。我只是说这是一个问题,而不是我有一个好的解决方案......
  • ...人们丢弃异常是 AssertionErrors 恕我直言的原因 ;)
【解决方案3】:

默认情况下没有任何问题。事实上,我相信它几乎总是应该用于抛出错误以指示开关中的错误值。

我能想到的唯一可能导致您的教授做出这样的陈述的原因是,他或她认为您的数据应该在达成案例陈述之前得到验证。即,如果您编程得当,您的案例将反映每一个意外情况。

好吧,如果是这样的话,那么我们就不需要例外了。异常的整个想法是处理意料之外的情况。如果它是合理可预期的,你会处理它。

所以,一定要在你的 switch 默认语句中抛出异常。

至于它们在内部是如何工作的?我相信有很多可能的实现,但从逻辑上讲,默认情况只是 if..then..if..then..else 的长链中的最后一个 else 子句。

【讨论】:

    【解决方案4】:

    是的,使用默认情况是一种很好的做法,因为如果以后您更改了在 switch 语句中使用的条件或枚举,应用程序的行为确实比不使用新值时“不那么不正确”完全覆盖。 很抱歉,但是 IMO 你的老师有点赶上最新的编程方法。

    在内部它是这样工作的,即使用默认分支以防万一,条件不匹配任何其他列出的条件。

    【讨论】:

      【解决方案5】:

      恐怕你的老师错了。默认情况下是一个很好的做法。

      【讨论】:

        【解决方案6】:

        对这个问题的另一种看法:

        其他答案基本上基本上是“当您在 X 上切换/大小写时,X 的类型允许 X 为 1、2、3 等(整数),或红色、蓝色、紫红色等(枚举) ,一定要处理等!!”。很明显,不是吗?

        另一方面,当您认为 X 作为一个变量时,由于程序流程的原因,它永远不会取值“etc”……否则,请考虑一下,因为它最终会取值。这是一般建议。

        从 Java/Pascal 的角度来看:如果 X 的类型不允许允许“etc”怎么办? (比如说,一个“非常严格”的枚举或一个范围(对于整数))。也就是说,编译器确保可能的值永远不会是“等”。并将未处理的情况标记为错误。会好的。 :-) 函数式语言具有模式匹配和代数类型,这种方式是这样的,但我在那里没有相关经验。 :(

        回到Java(和类似的语言),因为你可以实现类型(类),你可以实现严格检查,例如通过将“案例”作为采用 lambdas/functions/function 对象的方法调用...

        【讨论】:

          【解决方案7】:

          这真的取决于。如果没有默认值,则不需要。

          【讨论】:

          • IMO case 语句不过是一组 if-then-else 语句。我们总是需要设置一个 else case 吗?我不相信。
          • 是正确的,因为没有 else 的独立“if-then”是一种有用且常见的构造,但它主要用于逻辑主线出现异常时。例如, if (isFirstTimeLoading) populateDropdowns();开关盒很少用于这种情况,但它们可以。我认为重点是,“不要假设您知道所有情况。如果您可以通过使用默认情况来识别异常,那就去做吧。”。
          • 您是对的,您不需要 使用它。但是,您可以使用它。
          • 在某些情况下我会同意这一点。例如,如果您需要对大范围内的某些值进行特殊处理,并且默认情况也适用于这些元素,因此在切换之后编写。但是,根据我的经验,这种情况很少见。
          猜你喜欢
          • 1970-01-01
          • 2020-08-25
          • 1970-01-01
          • 2023-01-06
          • 2013-03-30
          • 1970-01-01
          • 2015-08-03
          • 1970-01-01
          • 2018-12-17
          相关资源
          最近更新 更多