[英]F# Code Execution Order
關於F#的另一個noob問題。
如果我有以下代碼......
let ExeC =
printfn "c"
3
let ExeB b =
printfn "b"
2
let ExeA =
printfn "a"
1
printfn "Example %d " ExeA
printfn "Example %d " (ExeB 1)
printfn "Example %d " ExeC
輸出如下......
c
a
Example 1
b
Example 2
Example 3
這里看起來很不尋常的是代碼執行的順序。在上一個問題中,Brian提到了一些關於表達式的問題,我希望有人可以解釋一下這個問題。 幾乎看起來編譯器是智能地預先執行事物來計算值...但我不知道?
ExeA
和ExeC
不是函數,而是單個值。 編譯器確保值按照在源文件中聲明的順序初始化,因此這里發生的是:
ExeC
初始化 ExeA
初始化 ExeA
的初始值打印Example 1
ExeB
函數被正常調用 ExeC
的初始值打印Example 3
如果你想讓ExeA
和ExeC
真正變得懶惰 - 也就是說,控制它們的副作用何時運行 - 你可以把它們變成接受unit
函數:
let ExeC () =
printfn "c"
3
let ExeB b =
printfn "b"
2
let ExeA () =
printfn "a"
1
printfn "Example %d " (ExeA ())
printfn "Example %d " (ExeB 1)
printfn "Example %d " (ExeC ())
作為Tim回答的后續內容,我想你可能會對你偶然發現的事情有所了解。 在您的示例中,ExeC和ExeA利用通過詞法作用域和閉包來組織代碼的功能樣式。 讓我展示一個更有力的例子。
let calc n =
//...
let timesPieDiv4 =
let pie = 3.14
let pieDiv4 = pie/4.
n * pieDiv4
//...
在這里, timesPieDiv4
不是一個函數,但它的主體包含一系列子計算,這些子計算不會暴露給其余的calc
函數。 在像C#這樣的語言中,你有兩種選擇,它們都不吸引我。 第一個選項是簡單地在calc
主體中聲明pie
和pieDiv4
,但是它們不太清楚它們是如何被使用的並且你弄臟你的變量空間。 另一種選擇是將這些子計算分解為一個單獨的私有輔助函數。 但是我不喜歡這樣的功能,因為很多人很難分析你的復雜算法,因為你總是在尋找各種實現部分。 此外,它還有很多鍋爐板代碼和價值傳遞。 這就是為什么F#函數默認是“公共”的,詞法作用域和閉包允許您在面向公眾的函數中分層組織“私有”函數和值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.