我有以下程序:
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
我希望获得以下输出(因为main是入口点,并且没有函数调用):
Ah! entering point to the main!
但是当我在VS 2013中编译并运行它时,我得到了这个:
Inside the let!
Ah! entering point to the main!
我的错误是什么?
答案 0 :(得分: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
观察到的行为非常有意义,因为跳出main来计算一个常量值是不合逻辑的。
要避免此问题,您希望将readStoriesInQAForm
设为一个函数,如下所示:
let readStoriesInQAForm() = ...
答案 1 :(得分:6)
正如John Palmer在他的回答中所描述的那样,F#代码是从上到下执行的。 let
关键字将值绑定到名称 - 在这种情况下,值0
绑定到readStoriesInQAForm
名称。
除了原始值,您还可以将函数绑定到名称; F#是一种功能编程语言,因此函数也是值。如果将函数绑定到名称,则可以通过调用它来执行该函数。
然而,readStoriesInQAForm
不是函数 - 它是原始值(0
),并且在调用main
之前它会被绑定,以便main
可用的值。在这种特殊情况下,定义let
绑定的方式,当绑定发生时,它具有<标准输出的副作用。 (一般来说,在功能编程中,你越能避免副作用,就越好。)
如果要避免此行为,请将let
绑定从原始值更改为函数:
let readStoriesInQAForm () =
printfn "Inside the let!"
0
更好的是将名称绑定到值而没有任何副作用:
let readStoriesInQAForm = 0
答案 2 :(得分:4)
你没有声明一个函数,你宣布了一个值。缺少()
:
let readStoriesInQAForm() =