【问题标题】:Does OCaml have the ability to pass by reference?OCaml 有没有通过引用传递的能力?
【发布时间】:2016-10-12 16:57:15
【问题描述】:
在 C++ 中,程序可以将引用而不是值传递给函数。
void incrementInt(int &x)
{
++x;
}
OCaml 是否提供相同的功能?
【问题讨论】:
标签:
c++
ocaml
pass-by-reference
【解决方案1】:
不,没有严格的等价物。
有refs,就像指向新分配的内存的指针,还有其他复合数据类型的记录、数组、对象和值,它们是“通过对象引用”传递的,这再次意味着它们起作用比如指向新分配内存的指针。
但是,没有等同于指向变量或 C++ 引用的指针。
【解决方案2】:
OCaml 中的按值传递和按引用传递之间没有明显的区别,因为在 OCaml 中不可能分配给变量。例如,您的++x 在 OCaml 中是不可能的。
按值传递和按引用传递之间的区别在于,在被调用函数内部分配参数时会发生什么——在按值传递中,它对传递的变量没有影响(如果传递了一个变量);在按引用传递中,它与在调用范围内对传递的变量赋值具有相同的效果。在 OCaml 中,您不能分配给变量,因此不存在这种区别。如果 OCaml 是“按引用传递”,它的工作方式与“按值传递”完全相同。
您可以传递对可变数据结构的引用,并使用它在函数之间共享状态,但这与传递引用无关,因为您可以在仅传递值的语言中执行此操作,例如C 和 Java。
【解决方案3】:
在 OCaml 中,参数是按值传递的。值本身可以是可变的,也可以是不可变的。前者可以被调用者修改,调用者可以看到。不可变的值,显然不能被修改。值的可变性由其类型定义。 OCaml 中的大多数值类型都是不可变的。值得注意的例外是数组和字符串(在新版本的 OCaml 中,字符串变得不可变,但让我们跳过这个话题)。例如,int 类型的值是不可变的。这是很自然的——如果你有数字5,它总是数字5,你不能改变它。但是,您可以将此数字放入可变单元格并将此单元格传递给函数。这样的功能,可以改变单元格的内容。请注意,我们并没有更改数字本身,我们只是将另一个数字放入同一个单元格中,例如,
type cell = {
mutable value : int;
}
let incr x =
x.value <- x.value + 1
incr 函数从单元格中获取一个值,通过增加它来创建一个新值,然后将 new 值放入单元格中。
我们可以参数化类型cell,这样它就可以包含任何类型的值,例如,
type 'a cell = {
mutable value : 'a;
}
事实上,ref 类型实际上看起来是一样的(模数名称)。在标准库中定义如下;
type 'a ref = {
mutable contents : 'a;
}
通过引用传递的概念是由泄露自己的抽象的语言创建的,这使得程序员有必要了解参数是如何传递给函数的。在 OCaml 中,您可以将其视为一场噩梦。 OCaml 中的每个参数只接受一个机器字,并通过寄存器传递,如果参数太多,则通过堆栈传递。从 C 程序员的角度来看,每个值都是标量或指针。整数和一元构造函数(变体)作为标量传递,其中复合数据类型始终由指针传递。
【解决方案4】:
最接近的,可能是:
let x=ref 3;;
let incrementInt x =
x := !x+1;;
incrementInt x;;
# !x;;
- : int = 4
如sepp2k所说,不一样。