13
let () = Random.self_init();;
let _ = Random.self_init ();;
│- : unit = ()

似乎“让()”什么也没返回?

真挚地!

4

2 回答 2

24

let是用于定义新变量的关键字,如以下构造:

let pattern = expr

例如

let a = 2

将值赋给2name a。(请注意,这不是为已经存在的变量赋值的方法,但这是另一个主题)。

=标志左侧的图案不仅仅是一个名字。例如

let (a,b) = (42,"foo")

定义ab, 分别为42"foo". 当然,双方的类型必须匹配。这里就是这种情况:双方都是 type int * string

符号右侧的表达式=也可以详细说明,例如

let foo =
  let temp = String.make 10 'a' in
  temp.[2] <- 'b';
  temp

定义foo为字符串"aabaaaaaaa"。(作为旁注,它还确保这temp是此代码片段的本地)。

现在,让我们同时使用:左边是匹配 type 值的模式unit,右边是 type 的表达式unit

let () = Printf.printf "Hello world!\n"

这解释了let () =构造。现在,关于let _,人们只需要知道它_可以在模式中用作通配符:它匹配任何类型的值并且不绑定任何名称。例如

let (a,_) = (42,"foo")

定义a42,并丢弃该值"foo"_意思是“我知道这里有一些东西,我明确表示我不会使用它,所以我没有命名它”。这里_用于匹配 type 的值string,但它可以匹配任何类型的值,例如int * string

let _ = (42,"foo")

它没有定义任何变量,也不是很有用。当右手边有副作用时,这样的构造很有用,如下所示:

let _ = Printf.printf "Hello world!\n"

这解释了问题的第二部分。



实际用途

两者都被使用,使用一个或另一个是一个口味问题。

let () =稍微安全一些,因为它让编译器检查右侧是否为unit. 除单位以外的任何其他类型的值通常都是错误。

let _ =稍微短一些(我见过这个论点)。(请注意,使用自动关闭括号的编辑器,击键次数是相同的 ;-)

于 2012-07-17T07:27:00.720 回答
2

我不是 OCaml 专家,尽管让我分享一些东西:)

letOCaml 中的可以代表两件事:

  1. 分配变量的方式;
  2. 您可以声明函数或将函数分配给名称的方式;

使用示例,您可以清楚地看到它是如何工作的: 分配变量:

# let ten = 10;;
val ten : int = 10

# let hello_world_string = "Hello World";;
val hello_world_string : string = "Hello World"

声明函数:

# let sum a b = a+b;;
val sum : int -> int -> int = <fun>
# sum 2 3;;
- : int = 5

因此,回答 let ()= 和 let _= 之间的区别的问题是:

在第一个示例中,您要声明一个没有名称、参数或指令的函数,该函数应该输出一个单元。第二个示例,您没有分配给 _,即 OCaml 的通配符,任何值。

正如我们在下面看到的,我们可以定义一个函数,该函数将立即执行,因为我们将无法再调用它:

# let () = print_string "Hello";;
Hello

或者为 OCaml 的通配符分配一个类型和值,或者一个函数:

# let _ = 10;;
- : int = 10
# let _ = print_string "Maybe I answered your question :) ";;
Maybe I answered your question :) - : unit = ()
于 2012-07-17T03:31:34.163 回答