我认为在F#中使用匹配表达式比while循环和if语句更有意义,但是我无法使其正常工作。该代码对我来说看起来不错,并且没有任何错误。有人可以解释为什么它不起作用吗?
open System
let width = Console.WindowWidth
let height = Console.WindowHeight
let rec main() =
let x = Console.CursorLeft
let y = Console.CursorTop
match Console.ReadKey().Key with
| ConsoleKey.UpArrow -> Console.SetCursorPosition(x, (y - 1))
| ConsoleKey.RightArrow -> Console.SetCursorPosition((x + 1), y)
| ConsoleKey.DownArrow -> Console.SetCursorPosition(x, (y + 1))
| ConsoleKey.LeftArrow -> Console.SetCursorPosition((x - 1), y)
| _ -> main()
main()
Console.ReadKey() |> ignore
答案 0 :(得分:4)
您遇到的问题是定义了main()
函数之后,您再也不会调用它。
这是您的代码现在的样子:
let rec main() =
// The definition of main()
Console.ReadKey() |> ignore
请记住,在F#中,缩进非常重要:在let someName =
声明之后,下一个缩进块的其余部分就是函数的主体。因此,您的代码中只有两个顶级表达式:一个定义了从未调用的名为main()
的函数,另一个是从控制台读取键的表达式。在F#中,命名函数main()
没有什么特别的。要使函数成为程序的入口点(运行程序时首先要运行的东西),you need to declare it with the EntryPoint
attribute:
[<EntryPoint>]
let rec main() =
// The definition of main()
还要注意文档中关于隐式入口点的说法:
当程序没有明确指示入口点的
EntryPoint
属性时,将要编译的最后一个文件中的顶级绑定用作入口点。
您向我们展示的程序中的“顶级绑定”有两件事:定义一个函数,然后读取一个键。
将EntryPoint
属性放在您的let rec main() =
行之前,我怀疑这会解决您的问题。或者,如果您以.fsx
脚本的形式运行此脚本,那么[<EntryPoint>]
是不正确的方法,而您需要在目录的顶层调用main()
程序(在定义之后)。