【问题标题】:Regarding Java switch statements - using return and omitting breaks in each case关于 Java switch 语句 - 在每种情况下使用 return 并省略中断
【发布时间】:2023-10-31 15:20:02
【问题描述】:

鉴于这种方法,这是否代表了一些令人震惊的文体或语义失礼:

private double translateSlider(int sliderVal) {
    switch (sliderVal) {
        case 0:
            return 1.0;
        case 1:
            return .9;
        case 2:
            return .8;
        case 3:
            return .7;
        case 4:
            return .6;
        default:
            return 1.0;
    }
}  

显然不符合 Java 教程here

但是,它清晰、简洁,到目前为止已经完全满足了我的需求。是否有一个令人信服的、务实的理由来创建一个局部变量,在每个案例中为其分配一个值,为每个案例添加一个中断并在方法结束时返回值?

【问题讨论】:

  • 这对我来说很好。 switch 语句是该方法的唯一内容,并且清晰易读,因此非常有意义。

标签: java return switch-statement case break


【解决方案1】:

虽然这个问题已经足够老了,但现在仍然可以参考。

从语义上讲,这正是 Java 12 引入的 (https://openjdk.java.net/jeps/325),因此,在这个简单的示例中,只要我看不到任何问题或缺点。

【讨论】:

    【解决方案2】:

    人类逻辑到计算机生成字节码的最佳情况是使用如下代码:

    private double translateSlider(int sliderVal) {
      float retval = 1.0;
    
      switch (sliderVal) {
        case 1: retval = 0.9; break;
        case 2: retval = 0.8; break;
        case 3: retval = 0.7; break;
        case 4: retval = 0.6; break;
        case 0:
        default: break;
      }
      return retval;
    }
    

    因此消除了方法的多个出口并在逻辑上使用该语言。 (即当sliderVal 是1-4 的整数范围时,改变float 值,否则如果sliderVal 为0 和所有其他值,retval 保持相同的float 值1.0)

    然而,像这样的情况,sliderVal 的每个整数值都是 (n-(n/10)) 真的可以只做一个 lambda 并获得更快的结果:

    private double translateSlider = (int sliderVal) -> (1.0-(siderVal/10));
    

    编辑: 模数为 4 可能是为了保持逻辑(即(n-(n/10))%4)

    【讨论】:

    • 您需要将break; 添加到上面的每个case - 目前1-4 将全部落入retval = 0.6
    • 哇,2015 年.. 绝对成长为一名开发人员。回顾这段代码;人们开始思考,“为什么不将其实现为带有哈希图的查找表。”
    【解决方案3】:

    从人类智能的角度来看,您的代码很好。从静态代码分析工具来看,有多个返回,这使得调试变得更加困难。例如,您不能在返回之前立即设置一个且唯一的断点

    此外,您不会在专业应用程序中对 4 个滑块步骤进行硬编码。 通过使用 max - min 等计算值,或者 在数组中查找它们:

    public static final double[] SLIDER_VALUES = {1.0, 0.9, 0.8, 0.7, 0.6};
    public static final double SLIDER_DEFAULT = 1.0;
    
    
    private double translateSlider(int sliderValue) {
      double result = SLIDER_DEFAULT;
      if (sliderValue >= 0 && sliderValue < SLIDER_VALUES.length) {
          ret = SLIDER_VALUES[sliderValue];
      }
    
      return result;
    }
    

    【讨论】:

    • 这里使用数组有一个缺点。数组中的索引隐式对应于可能的滑块输入值。但这是非常隐含的。如果有人决定让滑块从 1 开始或以 5 为增量移动会发生什么?从长远来看,使用从滑块值到输出值的映射 (HashMap) 可能更灵活。无论哪种方式,这都比通过 switch 语句跳跃更快的操作,所以很好
    【解决方案4】:

    我认为你写的很好。我也没有看到有多个返回语句的任何可读性问题。

    当我知道要返回时,我总是更喜欢从代码中的点返回,这将避免在返回下方运行逻辑。

    可以有一个参数用于调试和日志记录的单个返回点。 但是,在您的代码中,如果我们使用它,则不存在调试和日志记录的问题。就像你写的那样简单易读。

    【讨论】:

      【解决方案5】:

      将值分配给局部变量,然后在最后返回该值被认为是一种很好的做法。具有multiple exits are harder to debug 的方法可能难以阅读。

      也就是说,这是这个范式剩下的唯一优点。它起源于只有低级程序语言出现时。在那个时候它更有意义。

      当我们讨论这个主题时,您必须check this out。读起来很有趣。

      【讨论】:

      • 链接一个 SO 帖子并说多个出口不好。到目前为止,对该问题的最高投票答案以“这在很大程度上取决于个人喜好”开始,并以“强制执行单个退出点是毫无意义甚至适得其反的限制恕我直言”结束。 -_- 长叹
      • @MillieSmith 在任何一个投票最多的答案中都没有或没有说任何事情。我错过了什么吗?
      • @MillieSmith 哦,我点击了另一个链接。解释了为什么我没有看到它大声笑
      • @MillieSmith 用户指出了关于该主题的所有不同流派,并在最后陈述了他的观点,似乎还可以。
      【解决方案6】:

      为什么不直接

      private double translateSlider(int sliderval) {
      if(sliderval > 4 || sliderval < 0)
          return 1.0d;
      return (1.0d - ((double)sliderval/10.0d));
      }
      

      还是类似的?

      【讨论】:

      • 这不像您的解决方案那样在计算上“快速”,因此如果您希望节省周期,浮点运算可能不是一个好的选择 - 或者如果您正在寻找更多的“配置”(也就是说,数学并不总是这么好)。
      • @SubSeven 当用户用缓慢的手指移动滑块时,永远不需要保存循环。即使是最慢的嵌入式设备也远远胜过他的手指。代码的可读性和清晰性是最大的。
      • 硬编码的 4,触发另一个警告(幻数)
      • 不应该是 if (sliderVal > 0 && sliderVal
      【解决方案7】:

      是的,这很好。 教程并不总是简洁而整洁。 不仅如此,创建局部变量既浪费空间又低效

      【讨论】:

      • 您在 IDK 中学习了这种骇客,但本地变量总是被垃圾收集器删除,并且只保留在方法的上下文中,因为它因此而不会效率低下或“浪费空间”。
      【解决方案8】:

      如果您要拥有一个只运行开关然后返回一些值的方法,那么请确保这种方法有效。但是,如果您想在方法中使用其他内容进行切换,则不能使用 return,否则方法中的其余代码将不会执行。请注意教程中的代码后如何打印?你的将无法做到这一点。

      【讨论】:

        【解决方案9】:

        我建议你不要使用文字。

        除了样式本身看起来不错。

        【讨论】:

        • 比较在哪里?开关在 int 上。
        • 在我自欺欺人的头脑中 :) 误读,认为双重回报是 case 声明。
        【解决方案10】:

        不,你所拥有的一切都很好。您也可以将其作为公式 (sliderVal &lt; 5 ? (1.0 - 0.1 * sliderVal) : 1.0) 或使用 Map&lt;Integer,Double&gt;,但您所拥有的就可以了。

        【讨论】:

        • 这不会给出与 OP 代码相同的返回值。 0.1 没有精确的二进制表示,并且通过将其与 sliderVal 相乘,您正在复合精度误差。
        • @RohitJain 在一般情况下,当然;但在这种情况下,你会得到与0 &lt;= i &lt;= 10 相同的值:ideone.com/3F9y8K。如果 OP 无论如何都在使用双打,很有可能会有其他舍入错误需要处理,因为这些都是课程的标准。
        • 那个?不鼓励操作员:您提出的解决方案解决了多个返回警告,但触发了?操作员警告
        • @AlexWien“气馁”?不要让这听起来像是一个绝对的规则;有很多人对无链的三元运算符感到满意。如果您不喜欢它,请对您脑海中的 if-else 进行微不足道的扩展;我的主要观点是,这个问题可以在不加强 6 个选项的情况下解决。
        • 地图是个坏主意。在这里不需要用大炮射击小鸟(可能翻译得不好)。一个简单的固定数组就足够了。
        最近更新 更多