【问题标题】:Should an if statement be associated with else statement in ocaml?if 语句是否应该与 ocaml 中的 else 语句相关联?
【发布时间】:2019-11-24 06:09:27
【问题描述】:

在 ocaml 中,我希望有许多嵌套的 if 语句和每个条件的返回值。代码变得像这样复杂。

let func arg1 arg2 = 
   if condition1 then arg1+arg2
   else
   (
       //code1
       if condition2 then arg1*arg2
       else
       (
          //code2
          if condition3 then arg1+arg2
          else
          (
             //code3
          )
       )
   )

我可以用这样的代码代替这样的嵌套语句吗?

let func arg1 arg2 = 
   if condition1 then arg1+arg2
   //code1
   if condition2 then arg1*arg2
   //code2
   if condition3 then arg1+arg2
   //code3

【问题讨论】:

  • 看起来你正在实现一个解释器,所以我猜condition1 等可以写成模式匹配子句,语言很好地支持它并避免嵌套条件(它们是更像switch,但更聪明)。回答一般问题:不,没有办法提前返回(除了例外)。您可以使用嵌套不明显的编码样式。
  • @coredump。不,我没有实现解释器。我只是举了这个例子来简化问题。我的实际返回值不同,示例中提到的 if 条件之间有很多代码行。

标签: if-statement return ocaml


【解决方案1】:

您可以使用不带elseif 语句,如果它返回类型为unit 的值(基本上当它 某事时)。

if condition then print_int 3

但是,在您的情况下,您希望返回 int 类型的值,因此 else 分支是强制性的。不过可以使用else if 语句缩短它。

if condition1 then arg1+arg2
else if condition2 then arg1*arg2
else if condition3 then arg1+arg2
else arg1

请注意,最后需要使用else

模式匹配也可以扩展为使用when子句验证某些条件:

match 3 with
| 0 -> 0
| 1 -> 1
| x when x mod 2 = 0 -> x/2
| x when x mod 3 = 0 -> x/3
| x -> x

【讨论】:

    【解决方案2】:

    OCaml 是一种强静态类型语言,这意味着在编译时检查每个表达式的类型。

    看看下面的sn-p。

    if condition then true_value else false_value
    

    在编译期间,类型检查器将检查以下内容:

    1. condition 必须有 bool 类型;
    2. true_value 必须与false_value 具有相同的类型;
    3. 整个表达式的类型与true_valuefalse_value 相同。

    如果其中任何一个语句不正确,则编译失败并出现类型错误。


    现在,让我们看看没有elseif 语句。

    if condition then true_value
    

    如果条件为假,则表达式的计算结果为(),这是unit 类型的唯一值。使用前面的语句 2 和 3,true_value 在此处可以拥有的唯一类型是 unit。这意味着您不能使用 intstring 或任何作为 true_value 的东西。


    通常,深层嵌套的if-else 语句被视为code smell:它可能表明您的代码需要重构。例如,OCaml 提供pattern-matching。根据您的实际代码的样子,这可能是要走的路。

    【讨论】:

    • 轻微吹毛求疵:表达式不会计算为空,而是 ()unit 类型的唯一值。
    • 如果说“if then”结构有一个隐含的else () 可能更简单。
    【解决方案3】:

    仅供参考,您不需要所有这些括号。 else 之后的任何内容都被视为“else”分支中的单个表达式。你可以写你的代码像

    let func arg1 arg2 = 
      if condition1 then arg1+arg2 else
      (* code1 *)
    
      if condition2 then arg1*arg2 else
      (* code2 *)
    
      if condition3 then arg1+arg2 else
      (* code2 *)
    

    【讨论】:

    • 这在很大程度上取决于(* code1 *) 的实际情况。特别是,如果你有if condition1 then arg1+arg2 else print_endline "in else branch"; if condition2 then ... 之类的东西,else 将以分号结尾(你会得到一个类型错误,因为then 的类型为intelse 的类型为unit)。一般来说,将( ... )begin ... end 放在分支(thenelse)周围,只要它们不是完全无关紧要的,通常会提供更具可读性和可维护性的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-16
    • 2016-04-05
    • 2017-08-29
    • 1970-01-01
    相关资源
    最近更新 更多