[英]F# strange printfn problem
我正在玩F#(Visual Studio 2010 beta 1),我寫了一個小的控制台腳本,要求用戶輸入2個數字和一個操作符,然后執行它。 它工作正常,除了一個微小但令人煩惱的事情:有時我的printfn指令被忽略。 我在代碼中放置了斷點,以確定情況確實如此。
代碼段:
let convert (source : string) =
try System.Int32.Parse(source)
with :? System.FormatException ->
printfn "'%s' is not a number!" source;
waitForExitKey();
exit 1
let read =
printfn "Please enter a number.";
System.Console.ReadLine
let num1 : int = read() |> convert // the printfn in the read function is run...
let num2 : int = read() |> convert // ... but here is ignored
這當然不是完整的來源,但我認為這就足夠了。 如果您需要完整的來源,請告訴我。
所以我的問題很簡單:printfn導致這個問題的原因是什么? 難道我做錯了什么?
提前謝謝,ShdNx
這個頁面部分解釋了發生了什么,但簡短而甜蜜的版本是F#如果沒有參數,將在聲明上執行任何值。
let read =
printfn "Please enter a number."
System.Console.ReadLine
由於read
不接受任何參數,因此它會在聲明時立即執行,並將函數的返回值綁定到read
的標識符。
順便提一下,您的返回值恰好是類型(unit -> string)
的函數。 這是因為如果沒有傳遞所有參數,F#會自動調整函數 。 ReadLine
需要一個單元參數,但由於它沒有被傳遞,所以實際上將read
綁定到ReadLine
函數本身。
解決方案如下:
let read() = // read takes one unit parameter
printfn "Please enter a number."
System.Console.ReadLine() // pass paramter to ReadLine method
由於read
接受一個參數,因此每次調用時都會重新評估。 另外,我們將一個參數傳遞給ReadLine
,否則我們只會將ReadLine
函數作為值返回。
我知道這可能令人困惑。 在您的示例中, printfn
比您想象的更早運行。 即使沒有調用read()
,它實際上也會執行,即注釋掉最后兩行,你仍然會看到正在打印的消息。
我認為你的意圖是這樣的:
let read() =
printfn "Please enter a number.";
System.Console.ReadLine()
這將創建一個“可重用”函數,而不是像在原始示例中那樣將函數綁定到標識符。
作為旁注,這里使用分號是可選的,所以你可以寫:
let read() =
printfn "Please enter a number."
System.Console.ReadLine()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.