你在 OCaml 的第一个项目

既然 OCaml 发行版可以在你最喜欢的操作系统上使用,我们可以在 OCaml 中创建你的第一个程序:Hello World!

我们有不同的方式来启动 OCaml 程序。

REPL(顶级)

你可以使用顶层以**交互方式执行代码。使用 OCaml toplevel ,你可以编写和执行 OCaml 代码,作为 UNIX shell。之后,顶层会立即检查你的代码类型。因此,你可以快速轻松地测试代码的某些部分,而无需编译和执行。 ** ** **

你可以使用 ocaml 命令启动顶层。然后,你可以写一个由 ;; 结束的 OCaml 句子,立即评估。在顶层显示的类型和你的表达刚过的价值:

# "Hello Worlds!";;
- : string = "Hello Worlds!"

也可以在文件上启动顶层。你可以看到这个解释

为方便你在顶层输入,你可以使用像 leditrlwrap 这样的工具,它提供了一些功能(如输入历史记录):

 $ ledit ocaml

 $ rlwrap ocaml

编译为字节码

我们有两个不同的编译器,一个编译为字节码,另一个编译为本机代码。第一个与 Java 虚拟机的字节码相同。因此,字节码效率较低,但更便携。

我们有一些 OCaml 编译器使用的扩展文件:

延期 定义
.ml 源代码(如 C 中的 .c
.mli 界面(如 C 中的 .h
.cmo ocamlc字节码中编译的源代码 **
.cmi 接口代码由 ocamlc 编译
.cmx.o 源代码由 ocamlopt 在本机代码中编译
.cma 字节码中的库(一些*.cmo 的桶) **
.cmxa.a 本机代码中的库
.cmxs 本机代码中的库(加载动态)

字节码编译器是 ocamlc

你有不同的常见选项:

  • -c:编译没有链接过程的源文件(生成可执行文件)。因此,命令 ocaml -c foo.ml 生成一个 .cmo 文件。与不需要编译头文件的 C 不同,在 OCaml 中编译 .mli 文件是必要的:ocaml -c foo.mli

你需要先编译接口。之后编译源文件时,OCaml 会尝试检查实现是否与接口匹配。

.mli 文件不是强制性的。如果你编译一个没有 .mli 文件的 .ml 文件,OCaml 会自动生成一个 .cmi 文件。

  • -o:将一些 .cmo 文件编译成可执行文件。例如:ocamlc -o program foo.cmo bar.cmo。这些文件需要由第一个文件没有依赖关系的依赖项排列。

  • -I:表示编译器可以找到编译所需文件的其他目录(如接口或源代码)。它与 C 编译器中的 -I 相同。

我们还有很多其他选择。你可以查看手册以获取更多信息。

所以,你现在可以编写 hello.ml,并使用 ocamlc -o hello hello.ml 编译此文件以生成字节码程序:

let () = print_endline "Hello World!"

let () = ... 是你程序的第一个条目(如 C 中的 main)。之后,我们使用函数 print_endline(由标准库提供)和参数 Hello World! 来打印 Hello Worlds,并在标准输出中添加换行符。

编译完成后,你将获得 .cmo 文件和编译器以及程序 hello 自动生成的 .cmi 文件。你可以打开你的程序,在此文件的顶部,你可以看到:

#!/usr/local/bin/ocamlrun

这意味着你的程序需要 ocamlrun 程序(由发行版提供)来执行字节码 (如 JVM)。

编译到本机代码

我们有另一个生成本机代码的编译器。编译器是:ocamlopt。但是,生成的可执行文件无法在大多数其他体系结构上运行。

ocamlopt 使用与 ocamlc 相同的选项,因此你可以执行 ocamlopt -o hello hello.ml。之后,你可以看到 .cmx.o 文件。

最后,从你的字节码 /本机代码程序中,你可以执行:

$ ./hello
Hello World!
$