Ocaml-全局变量 vs 局部变量

3

我想创建一个名为result的全局变量,使用5次字符串拼接来创建一个包含9个start字符串的字符串(由逗号分隔)。

我有两段代码,只有第二段声明了一个全局变量。由于某种原因,这很难在我的大脑中理解...难道是因为我在第一段代码中使用了let,所以result是一个局部变量吗?还有更详细的解释吗?

let start = "ab";;

let result = start ^ "," in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ start in 
  result;;
- : string = "ab,ab,ab,ab,ab,ab,ab,ab,ab"

let result = 
  let result = start ^ "," in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ start in 
  result;;
val result : string = "ab,ab,ab,ab,ab,ab,ab,ab,ab"
3个回答

6
让我来讲解一下。OCaml 中不存在局部变量和全局变量。这个概念来自于具有不同作用域规则的语言。此外,“变量”这个词本身应该小心使用。它的含义被类似 C 的语言歪曲了。这个词的原始数学含义对应于某些数学对象的名称,该对象在公式中使用,表示这些值的范围。在类似 C 的语言中,变量与可以随时间改变的内存单元混淆了。因此,为避免混淆,让我们使用更准确的术语。让我们使用“名称”代替“变量”。由于变量... 抱歉,名称不是内存单元,因此没有什么可以创建的。当您使用其中一个 let 语法时,实际上是创建一个绑定,即名称和值之间的关联。let = in 将 的值绑定到 <expr-2> 表达式的作用域中。let = in 本身也是一个表达式,因此,例如 <expr-2> 中也可以包含 let ... in ... 构造,例如:
 let a = 1 in
   let b = a + 1 in
     let c = b + 1 in 
       a + b + c

我特意以非习惯性的方式缩进代码,以突出表达式的语法结构。OCaml还允许使用已经在作用域中绑定的名称。新的绑定将隐藏现有的绑定(例如,C语言不允许这样做)。例如:

  let a = a + 1 in
    let a = a + 1 in
      let a = a + 1 in
          a + a + a

最后,顶层(也称为模块级别)的绑定(在OCaml术语中称为定义),其语法为:let <name> = <expr>,请注意这里没有in。该定义将<name>绑定到从定义点到封闭模块结束时词法范围内<expr>的评估结果。当您实现一个模块时,您必须使用let <name> = <expr>将您的代码绑定到名称(您可以使用_省略名称)。这与交互式toplevel(交互式ocaml程序)略有不同,后者实际上接受一个表达式并对其进行评估。例如:

let result = start ^ "," in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ start in 
  result

这不是一个有效的OCaml程序(不能放在ml文件中并进行编译),因为它是一个表达式,而不是模块定义。


1
基本上是这样的。定义全局变量的语法是 let variable = expression,不需要 in。定义局部变量的语法是 let variable = expression in expression,这将在 in 后的表达式中定义局部变量 variable

0

当你使用 let ... in 时,你声明了一个局部变量。当你只是在模块的顶层使用 let(也就是说,在模块中),你声明了该模块的全局名称。(即,可以从模块中导出的名称。)

你的第一个示例完全由 let ... in 组成。因此没有声明顶层名称。

你的第二个示例有一个 let 单独使用,后面跟着几次 let ... in 的出现。因此它声明了一个顶层名称 result


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接