多个文件的声明和全局引用变量

Sof*_*mur 5 variables ocaml runtime declaration

我的文件夹中包含多个文件,这是按以下顺序编译:global.ml,zone.ml,abs.ml,main.ml

global.ml包含一些let g1 = ref 0所有文件的引用变量(例如).

zone.ml有一个声明let f = !g1.

abs.ml,g1 := 5运行时main开始运行,我认为它是g1给定真实运行时上下文的初始化.

稍后main会打电话Zone.f.奇怪的是,我意识到需要的是f = 0代替f = 5.

你觉得这种行为是正常的吗?如果是这样,我应该改变什么,以使它考虑到当前的价值!g1

PS:也许一个解决方案是让一个函数let f v = vzone.ml,然后让main调用Zone.f !g1.但我为有好几个全球参考变量g1global.ml,我希望他们能超过所有的文件和功能有效,我不想让他们参与一个函数的签名.

Jef*_*eld 6

您基本上关注模块中顶级值的评估顺序.发生这种情况的顺序与编译文件的顺序无关,而是与链接文件时出现的顺序无关.

如果忽略模块边界,如果按照给出的顺序链接文件,那么你拥有的是这样的:

let g1 = ref 0
let f = !g1
let () = g1 := 5
Run Code Online (Sandbox Code Playgroud)

f值为0 应该不足为奇.

请注意,您main不一定是在运行时发生的第一件事.顶级值按链接它们时文件显示的顺序进行评估.很常见的main是,最后一个顶级的事情发生(因为它的文件通常是最后一个).

(还要注意,拥有一个main只是一个惯例,可能是像我这样的前C程序员所采用的.没有要求命名的函数main.OCaml只是按顺序评估顶级值.)

编辑:

很难说如何在不了解更多代码的情况下重构代码.您的问题的本质似乎是您将其定义f为顶级不可变值,zone.ml但您希望其值遵循g1,这是一个可变值.

最简单的建议是删除文件中的ffrom 的定义zone.ml并将其替换为文件中的任何位置!g1.

如果要f在顶层保留名称,则zone.ml必须将其重新定义为不可变值之外的其他值.功能是最明显的选择:

let f () = !g1
Run Code Online (Sandbox Code Playgroud)

然后你将替换fin zone.ml的用法f ().