簡體   English   中英

F#奇怪的printfn問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM