2012-02-05 33 views
5

我的文件夾中包含多個文件,這是按以下順序編譯:global.mlzone.mlabs.mlmain.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:也許一種解決方案是在zone.ml中生成函數let f v = v,然後讓main調用Zone.f !g1。但我有幾個全局引用變量g1global.ml,我希望它們可以在所有文件和函數中有效,並且我不想讓它們參與函數的簽名。

回答

6

你基本上是關心頂級值的評估在你的模塊的順序。在這種情況是不相關的,你編譯文件的訂單的訂貨,而是爲了使他們出現在你鏈接文件。

如果忽略該模塊的邊界,如果你在你給出的順序鏈接的文件,你有什麼是這樣的:

let g1 = ref 0 
let f = !g1 
let() = g1 := 5 

它不應該是不足爲奇的f的值是0

請注意,您的main不一定是運行時發生的第一件事。頂級值按文件在鏈接時出現的順序進行評估。很常見,main最後發生的頂級事情(因爲它的文件通常是最後一個)。

(另請注意,有一個main都只是一個慣例,由前C程序員喜歡我大概採納。有沒有要求有一個名爲main功能。OCaml的只是按順序評估頂層值)。

編輯:

這是很難說如何調整你的代碼,而更多地瞭解它。問題的實質似乎是,您在zone.ml中將f定義爲頂級不可變值,但您希望其值爲g1,這是一個可變值。

最簡單的建議是從zone.ml中刪除f的定義,並用!g1替換文件中的任何地方。

如果要在zone.ml的頂層保留名稱f,則必須將其重新定義爲不可變的值以外的值。函數是最明顯的選擇:

let f() = !g1 

然後你會被f()取代f用途在zone.ml代替。

+0

感謝您的評論,你解釋了爲什麼會發生,但你沒有解釋如何解決它......我不能改變這些文件的編譯順序,我還能做什麼? – SoftTimur 2012-02-05 13:35:31

+0

我添加**編輯**有一些建議。但如果不知道更多關於代碼的知識,很難知道該建議什麼。 – 2012-02-05 16:05:04