F# 条件表达式 if...then..else 返回单元或 ()
F# Conditional Expressions if...then..else returning unit or ()
F# 的条件表达式需要一个条件来检查,一个分支为真,一个分支为假。例如:
let x =
if ("hello" = null)
then true
else false //error if else branch missing
但是,当涉及到 unit
,又名 ()
时,事情会变得很奇怪。
let y =
if ("hello" = null)
then raise <| new ArgumentNullException()
else () //happy with or without else branch
更简单地说:
let z =
if ("hello" = null)
then ()
else () //happy with or without else branch
为什么返回 unit
时不需要 else
分支?
如果您从第一个片段中删除 else
,则等同于
let x =
if ("hello" = null)
then true
else ()
不进行类型检查。
为什么?我猜是为了与 OCaml 兼容。
The else expr3
part can be omitted, in which case it defaults to else ()
. (7.7.2)
你可以认为 unit
-returning if
相当于 C-like if
statement 而不是表达式.
考虑以下代码:
let f a = if a > 5 then true
如果你调用 f 10
,它 return 就是 true
。
现在,问问自己:f 2
return 应该做什么?我知道你会说 false
,但是编译器是怎么知道的呢?我的意思是,在这两种情况下,您的意思很可能是 return true
,不是吗?甚至,也许,在 a <= 5
情况下崩溃,谁知道呢?
因此,为了使程序成为 "complete"(即包含在每种情况下做什么的说明),您始终必须指定一个 else
分支。
然而,unit
是特殊的。
返回unit
表示没有有意义的return值。 unit
本质上代表副作用:它意味着 returned 的东西是为了在外部世界产生一些影响。由于 F# 不是一种纯语言,因此 unit
-return 这样的事情非常普遍。例如,调试日志记录:
let f x =
if x < 42 then printfn "Something fishy, x = %d" x
x + 5
有了这样的陈述,就没有歧义了:众所周知,else
分支也意味着 return ()
。毕竟 unit
没有其他值了,不是吗?同时,总是在末尾添加 else ()
会非常令人厌烦和混淆。因此,为了可用性,编译器在这种特定情况下不需要 else
分支。
问题已经回答了,所以我只是根据自己的肤浅观察跟进
在 F# 中,我们没有语句和表达式。在 F# 中,我们仅使用表达式来组合计算。这是一件好事。
在 C# 中,if
是一个有意义的语句
if(x)
{
return 1;
}
如果 x
为真,执行将停止,我们 return 向调用者返回结果:1
.
在 F# 中,if
是一个表达式,这意味着 if
应该产生一个值,而不管已经采取了哪个分支。因此这没什么意义
if x then 1 // What value should else branch evaluate to?
我们必须指定两个分支
if x then 1 else 0
正如其他答案所指出的那样,省略 else
是一种特殊情况。 if
表达式将产生一个 unit
值,这是我们在 F# 中获得的最接近语句的值。
因为 if
表达式的类型是 unit,所以 "true" 分支的类型必须是 unit
.
if x then () // This works
if x then () else () // This works
if x then 1 // This won't work, type mismatch
在 F# 中,if
是表达式而不是语句。每个表达式都需要 return 一个值。 if
和 else
都需要 return 相同类型的值,因为 F# 是强类型语言。因此,如果没有 else
分支,则默认情况下它的类型为 unit
,但如果您的 if
return 的值的类型不是 unit
,则您需要具有相同类型的 else
。
F# 的条件表达式需要一个条件来检查,一个分支为真,一个分支为假。例如:
let x =
if ("hello" = null)
then true
else false //error if else branch missing
但是,当涉及到 unit
,又名 ()
时,事情会变得很奇怪。
let y =
if ("hello" = null)
then raise <| new ArgumentNullException()
else () //happy with or without else branch
更简单地说:
let z =
if ("hello" = null)
then ()
else () //happy with or without else branch
为什么返回 unit
时不需要 else
分支?
如果您从第一个片段中删除 else
,则等同于
let x =
if ("hello" = null)
then true
else ()
不进行类型检查。
为什么?我猜是为了与 OCaml 兼容。
The
else expr3
part can be omitted, in which case it defaults toelse ()
. (7.7.2)
你可以认为 unit
-returning if
相当于 C-like if
statement 而不是表达式.
考虑以下代码:
let f a = if a > 5 then true
如果你调用 f 10
,它 return 就是 true
。
现在,问问自己:f 2
return 应该做什么?我知道你会说 false
,但是编译器是怎么知道的呢?我的意思是,在这两种情况下,您的意思很可能是 return true
,不是吗?甚至,也许,在 a <= 5
情况下崩溃,谁知道呢?
因此,为了使程序成为 "complete"(即包含在每种情况下做什么的说明),您始终必须指定一个 else
分支。
然而,
unit
是特殊的。
返回unit
表示没有有意义的return值。 unit
本质上代表副作用:它意味着 returned 的东西是为了在外部世界产生一些影响。由于 F# 不是一种纯语言,因此 unit
-return 这样的事情非常普遍。例如,调试日志记录:
let f x =
if x < 42 then printfn "Something fishy, x = %d" x
x + 5
有了这样的陈述,就没有歧义了:众所周知,else
分支也意味着 return ()
。毕竟 unit
没有其他值了,不是吗?同时,总是在末尾添加 else ()
会非常令人厌烦和混淆。因此,为了可用性,编译器在这种特定情况下不需要 else
分支。
问题已经回答了,所以我只是根据自己的肤浅观察跟进
在 F# 中,我们没有语句和表达式。在 F# 中,我们仅使用表达式来组合计算。这是一件好事。
在 C# 中,if
是一个有意义的语句
if(x)
{
return 1;
}
如果 x
为真,执行将停止,我们 return 向调用者返回结果:1
.
在 F# 中,if
是一个表达式,这意味着 if
应该产生一个值,而不管已经采取了哪个分支。因此这没什么意义
if x then 1 // What value should else branch evaluate to?
我们必须指定两个分支
if x then 1 else 0
正如其他答案所指出的那样,省略 else
是一种特殊情况。 if
表达式将产生一个 unit
值,这是我们在 F# 中获得的最接近语句的值。
因为 if
表达式的类型是 unit,所以 "true" 分支的类型必须是 unit
.
if x then () // This works
if x then () else () // This works
if x then 1 // This won't work, type mismatch
在 F# 中,if
是表达式而不是语句。每个表达式都需要 return 一个值。 if
和 else
都需要 return 相同类型的值,因为 F# 是强类型语言。因此,如果没有 else
分支,则默认情况下它的类型为 unit
,但如果您的 if
return 的值的类型不是 unit
,则您需要具有相同类型的 else
。