首页 > 解决方案 > 为什么在这个非常简单的打印命令中有语法错误

问题描述

我正在尝试运行以下非常简单的代码:

open Str
print (Str.first_chars "testing" 0)

但是,它给出了以下错误:

$ ocaml testing2.ml 
File "testing2.ml", line 2, characters 0-5:
Error: Syntax error

错误消息中没有更多详细信息。

同样的错误print_endline;或者即使没有打印命令。因此,错误部分是:Str.first_chars "testing" 0

来自here的有关上述功能的文档如下:

val first_chars : 字符串 -> int -> 字符串

first_chars sn 返回 s 的前 n 个字符。这与 Str.string_before 的功能相同。

在第二个语句的末尾添加;;;没有任何区别。

上述代码的正确语法是什么。

编辑: 使用@EvgeniiLepikhin 建议的以下代码:

open Str
let () =
    print_endline (Str.first_chars "testing" 0)

错误是:

File "testing2.ml", line 1:
Error: Reference to undefined global `Str'

并使用此代码:

open Str;;
print_endline (Str.first_chars "testing" 0)

错误是:

File "testing2.ml", line 1:
Error: Reference to undefined global `Str'

在上面的代码中只使用print命令(而不是print_endline),错误是:

File "testing2.ml", line 2, characters 0-5:
Error: Unbound value print

注意,我的 Ocaml 版本是:

$ ocaml -version
The OCaml toplevel, version 4.02.3

我认为Str应该是内置的,因为 opam 没有找到它:

$ opam install Str
[ERROR] No package named Str found.

我还尝试了@glennsl 评论中建议的以下代码:

#use "topfind"
#require "str"
print (Str.first_chars "testing" 0)

但这也同样简单syntax error

标签: syntax-errorocamlocaml-toplevel

解决方案


OCaml 程序是一个定义列表,按顺序进行评估。您可以定义值、模块、类、异常以及类型、模块类型、类类型。但到目前为止,让我们关注价值观。

在 OCaml 中,没有语句、命令或指令。它是一种函数式编程语言,其中一切都是表达式,并且在计算表达式时会产生一个值。该值可以绑定到一个变量,以便以后可以引用它。

print_endline函数接受一个 type 的值,将string其输出到标准输出通道并返回一个 type 的值unit。类型unit只有一个值,称为单元,可以使用()表达式构造。例如,print_endline "hello, world"是产生此值的表达式。我们不能只是在文件中抛出一个表达式并希望它被编译,因为表达式不是定义。定义语法很简单,

let <pattern> = <expr>

其中是变量或数据构造函数,它将与<expr>模式中出现的变量产生的值的结构相匹配,也可能是绑定变量,例如,以下是定义

let x = 7 * 8
let 4 = 2 * 2 
let [x; y; z] = [1; 2; 3]
let (hello, world) = "hello", "world"
let () = print_endline "hello, world"

您可能会注意到,print_endline "hello, world"表达式的结果没有绑定到任何变量,而是与unitvalue匹配(),可以看到(并且确实看起来像)一个空元组。你也可以写

let x = print_endline "hello, world"

甚至

let _ = print_endline "hello, world"

但是,在您所期望的定义的左侧明确说明总是更好。

所以,现在我们的格式良好的程序应该是这样的

 open Str

 let () = 
    print_endline (Str.first_chars "testing" 0)

我们将使用它ocamlbuild来编译和运行我们的程序。该str模块不是标准库的一部分,因此我们必须告诉ocamlbuild我们将要使用它。我们需要创建一个新文件夹并将我们的程序放入一个名为 的文件example.ml中,然后我们可以使用以下命令对其进行编译

 ocamlbuild -pkg str example.native --

ocamlbuild工具将从后缀推断出native您的目标是什么(在这种情况下,它是构建本机代码应用程序)。该--装置在编译后立即运行构建的应用程序。上面的程序不会打印任何内容,当然,这里有一个程序示例,它会在打印testing字符串的前零个字符之前打印一些问候消息,

open Str

let () =
  print_endline "The first 0 chars of 'testing' are:";
  print_endline (Str.first_chars "testing" 0)

这就是它的工作原理

$ ocamlbuild -package str example.native --
Finished, 4 targets (4 cached) in 00:00:00.
The first 0 chars of 'testing' are:

此外,您可以使用提供交互式解释器example.ml的顶级工具直接解释文件,而不是编译程序并运行生成的应用程序。ocaml您仍然需要将str库加载到顶层,因为它不是预链接在其中的标准库的一部分,这是正确的调用

ocaml str.cma example.ml

推荐阅读