问题
In ocaml, I want to have many nested if statements and a return value on each of the conditions. The code is becoming complicated like this.
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
)
)
)
Instead of such nested statements can I have code like this?
let func arg1 arg2 =
if condition1 then arg1+arg2
//code1
if condition2 then arg1*arg2
//code2
if condition3 then arg1+arg2
//code3
回答1:
OCaml is a strongly and statically typed language, which means that the type of every expression is checked at compile-time.
Take a look at the following snippet.
if condition then true_value else false_value
During compilation, the type-checker will check for the following:
condition
must have typebool
;true_value
must have the same type asfalse_value
;- The whole expression has the same type as
true_value
andfalse_value
.
If any one of these statements is not true, then the compilation fails with a type error.
Now, let's take a look at a if
statement, without a else
.
if condition then true_value
If the condition is false, then the expression evaluates to ()
, the only value of type unit
. Using statements 2 and 3 from before, the only type that true_value
can have here is unit
. That means that you can't use int
or string
or anything as the true_value
.
Usually, deeply nested if-else
statements is considered a code smell: it may indicate that your code needs refactoring. For instance, OCaml offers pattern-matching. Depending on what your actual code looks like, it may be the way to go.
回答2:
You can use an if
statement without a else
if it returns a value of type unit
(basically when it only does something).
if condition then print_int 3
However, in your case, you want to return a value of type int
and as such the else
branch is mandatory. It can nonetheless be shortened using else if
statements.
if condition1 then arg1+arg2
else if condition2 then arg1*arg2
else if condition3 then arg1+arg2
else arg1
Note that once again, you need to use else
at the end.
Pattern-matching can also be extended to verify some conditions using when
clauses:
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
回答3:
Just fyi, you don't need all those parentheses. Anything that comes after an else
is considered to be a single expression in the 'else' branch. You could write your code like
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 *)
来源:https://stackoverflow.com/questions/57041443/should-an-if-statement-be-associated-with-else-statement-in-ocaml