有像
这样的代码let () = print_string "something" in
fn
在一些OCaml代码中。
这是什么意思? “()”有特殊含义吗?或者与
的含义相同print_string "something";
fn
答案 0 :(得分:13)
此()
表达式中let
没有什么特别之处,它只是一种模式。所有let
表达式都显示为let
pattern
=
expression
in
other-expression
的。此处模式始终匹配,因为print_string
返回unit
,而()
是该类型的唯一值。通过这种方式,当第一个表达式更多地是一个语句(返回unit
)时,它只是将两个表达式组合成一个表达式的另一种方式。
所以你是对的,这个结构与使用;
运算符的含义几乎相同。唯一真正的区别在于优先权。例如,如果你写了
if x < 3 then
print_string "something";
f x
您会发现f x
总是被调用。 ;
的优先级太低,无法将第二个表达式置于if
的控制之下。这就是许多人(包括我)养成使用let () =
expression
的习惯的原因。如果你把上面的内容写成
if x < 3 then
let () = print_string "something"
in f x
f x
仅在x
小于3时调用,这通常是我想要的。从本质上讲,let
的优先级远高于;
。
当然可能有其他方法可以获得这种效果,但使用let
的好处是你不必在代码中添加任何东西(如右括号或{{ 1}})。如果您将end
添加为调试语句,这是将更改保持在一个位置的本地方便的方法。
答案 1 :(得分:3)
杰弗里的回答绝对正确,但还有一点:
如果你写
fx "something";
fn
你搞砸了fx "something"
的结果类型,编译器将发出一个警告,在编译过程中可能会丢失。另一方面,如果你写:
let () = fx "something" in
fn
编译器将键入检查fx "something"
的结果是否可以与()
匹配,即它实际上是unit
类型。因此,如果你搞砸了,就会产生错误,这通常更安全。
还有可能写
let _ = fx "something" in
fn
只会获得Jeffrey提到的优先效果,但不会进行任何类型检查,因为_
可以与任何类型的值匹配。