F#中的入口点问题

Dan*_*iel 2 f#

我有以下程序:

let readStoriesInQAForm = 
    printfn "Inside the let!"
    0 

[<EntryPoint>]
let main argv = 
    printfn "Ah! entering point to the main!"
    System.Console.ReadKey() |> ignore
    0 // return an integer exit code
Run Code Online (Sandbox Code Playgroud)

我期望获得以下输出(因为main是入口点,并且没有函数调用):

Ah! entering point to the main!
Run Code Online (Sandbox Code Playgroud)

但是当我在VS 2013中编译并运行它时,我得到了这个:

Inside the let!
Ah! entering point to the main!
Run Code Online (Sandbox Code Playgroud)

我的错是什么?

Joh*_*mer 6

在F#程序中,代码基本上是从上到下运行,因此以后需要的任何值都可用.

例如,如果你写了:

[<EntryPoint>]
let main argv = 
    printfn "Ah! entering point to the main!"
    printfn readStoriesInQAForm
    System.Console.ReadKey() |> ignore
    0 // return an integer exit code
Run Code Online (Sandbox Code Playgroud)

观察到的行为非常有意义,因为跳出main来计算一个常量值是不合逻辑的.

要避免此问题,您需要创建readStoriesInQAForm一个函数,如下所示:

let readStoriesInQAForm() = ...
Run Code Online (Sandbox Code Playgroud)


Mar*_*ann 6

正如John Palmer在他的回答中所描述的那样,F#代码从上到下执行.的let关键字结合的值,以一个名称-在这种情况下,值0被绑定到readStoriesInQAForm名称.

除了原始值,您还可以将函数绑定到名称; F#是一种函数式编程语言,因此函数也是值.如果将函数绑定到名称,则可以通过调用它来执行该函数.

但是,readStoriesInQAForm它不是一个函数 - 它是一个原始值(0),它在main被调用之前被绑定,以便使该值可用main.在这种特殊情况下,let定义绑定的方式,它在发生绑定时具有打印到标准输出的副作用.(一般来说,在功能编程中,你越能避免副作用,就越好.)

如果要避免此行为,请将let绑定从原始值更改为函数:

let readStoriesInQAForm () = 
    printfn "Inside the let!"
    0
Run Code Online (Sandbox Code Playgroud)

更好的是将名称绑定到值而没有任何副作用:

let readStoriesInQAForm = 0
Run Code Online (Sandbox Code Playgroud)


Mar*_*zek 5

你不是在声明一个函数,而是在声明一个值。缺少了()

let readStoriesInQAForm() = 
Run Code Online (Sandbox Code Playgroud)