如何使用F#中的匹配表达式移动光标位置?

时间:2018-07-28 17:14:10

标签: f# expression match

我认为在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

1 个答案:

答案 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()程序(在定义之后)。