Visual Studio Code 中的 F# 入门

可以使用 Ionide 插件Visual Studio Code 中编写 F#,以通过 IntelliSense 和代码重构获得出色的跨平台轻量集成开发环境 (IDE) 体验。 请访问 Ionide.io 以了解有关该插件的详细信息。

若要开始,请确保已正确安装 F# 和 Ionide 插件

使用 Ionide 创建第一个项目

若要创建新 F# 项目,请打开命令行并使用 .NET CLI 创建新项目:

dotnet new console -lang "F#" -o FirstIonideProject

完成后,将目录更改为该项目并打开 Visual Studio Code:

cd FirstIonideProject
code .

项目在 Visual Studio Code 中加载后,你应在打开的窗口左侧看到 F# 解决方案资源管理器窗格。 这意味着 Ionide 已成功加载了刚刚创建的项目。 可以在此时间点之前在编辑器中编写代码,但一旦发生这种情况,便表示所有内容都已完成加载。

编写你的第一个脚本

将 Visual Studio Code 配置为使用 .NET Core 脚本后,请导航到 Visual Studio Code 中的资源管理器视图,并创建新文件。 将它命名为 MyFirstScript.fsx。

现在向它添加以下代码:

let toPigLatin (word: string) =
    let isVowel (c: char) =
        match c with
        | 'a' | 'e' | 'i' | 'o' | 'u'
        | 'A' | 'E' | 'I' | 'O' | 'U' -> true
        |_ -> false
    
    if isVowel word[0] then
        word + "yay"
    else
        word[1..] + string(word[0]) + "ay"

此函数会将单词转换为隐语形式。 下一步是使用 F# 交互窗口 (FSI) 进行求值。

突出显示整个函数(其长度应为 11 行)。 突出显示后,按住 Alt 键并点击 Enter。 你会注意到,屏幕底部会弹出一个终端窗口,其外观应类似于下面这样:

Example of F# Interactive output with Ionide

这执行了三个操作:

  1. 启动了 FSI 进程。
  2. 它已将突出显示的代码发送到 FSI 进程。
  3. FSI 进程对发送的代码进行了求值。

由于发送的内容是一个函数,因此现在可以使用 FSI 调用该函数! 在交互窗口中,键入以下内容:

toPigLatin "banana";;

应该会看到以下结果:

val it: string = "ananabay"

现在,让我们尝试使用元音作为第一个字母。 输入以下内容:

toPigLatin "apple";;

应该会看到以下结果:

val it: string = "appleyay"

函数似乎是在按预期方式工作。 恭喜,你刚刚在 Visual Studio Code 中编写了第一个 F# 函数,并使用 FSI 进行了求值!

注意

正如你可能已注意到的,FSI 中的行以 ;; 终止。 这是因为 FSI 允许输入多行。 末尾的 ;; 会让 FSI 知道代码何时完成。

解释代码

如果你不确定代码实际执行的操作,以下是分步说明。

如你所见,toPigLatin 是一个函数,它采用单词作为输入并将其转换为该单词的隐语表示形式。 此函数的规则如下所示:

如果单词中的第一个字符以元音开头,则将“yay”添加到单词的末尾。 如果它不以元音开头,则将第一个字符移动到单词的末尾,并向其添加“ay”。

你可能已在 FSI 中注意到以下内容:

val toPigLatin: word: string -> string

这表明 toPigLatin 是一个函数,采用 string 作为输入(名为 word),并返回另一个 string。 这称为函数的类型签名,这是 F# 的基本部分,是理解 F# 代码的关键。 如果在 Visual Studio Code 中将鼠标悬停在函数上方,也会注意到此内容。

在函数体中,你会注意到两个不同的部分:

  1. 一个名为 isVowel 的内部函数,通过模式匹配检查给定字符 (c) 是否与提供的模式之一匹配,从而可确定该字符是否为元音:

    let isVowel (c: char) =
        match c with
        | 'a' | 'e' | 'i' | 'o' | 'u'
        | 'A' | 'E' | 'I' | 'O' | 'U' -> true
        |_ -> false
    
  2. 一个 if..then..else 表达式,用于检查第一个字符是否为元音,并基于第一个字符是否为元音从输入字符构造返回值:

    if isVowel word[0] then
        word + "yay"
    else
        word[1..] + string(word[0]) + "ay"
    

因而 toPigLatin 的流程是:

检查输入单词的第一个字符是否为元音。 如果是,则将“yay”附加到单词的末尾。 否则,将第一个字符移动到单词的末尾,并向其添加“ay”。

关于此方面最后要注意的一点是:在 F# 中,没有从函数返回的显式指令。 这是因为 F# 是基于表达式的,在函数体中求值的最后一个表达式会确定该函数的返回值。 因为 if..then..else 本身是表达式,所以 then 块体或 else 块体的求值会确定 toPigLatin 函数返回的值。

将控制台应用转换为隐语生成器

本文前面的部分演示了编写 F# 代码的常见第一步:编写初始函数并使用 FSI 以交互方式执行该函数。 这称为 REPL 驱动的开发,其中,REPL 表示“读取-求值-打印循环”。 在你具有可实际工作的内容之前,这是一种非常好的方式来体验功能。

REPL 驱动的开发中的下一步是将工作代码移到 F# 实现文件中。 它随后可以由 F# 编译器编译为可执行的程序集。

若要开始,请打开先前使用 .NET CLI 创建的 Program.fs 文件。 你会注意到,其中已存在某些代码。

接下来,创建名为 PigLatin 的新 module,并将前面创建的 toPigLatin 函数复制到其中:

module PigLatin =
    let toPigLatin (word: string) =
        let isVowel (c: char) =
            match c with
            | 'a' | 'e' | 'i' | 'o' | 'u'
            | 'A' | 'E' | 'I' | 'O' | 'U' -> true
            |_ -> false
        
        if isVowel word[0] then
            word + "yay"
        else
            word[1..] + string word[0] + "ay"

此模块应位于 main 函数的上方和 open System 声明的下方。 声明的顺序在 F# 中十分重要,因此在文件中调用之前,需要先定义函数。

现在,在 main 函数中,对参数调用隐语生成器函数:

[<EntryPoint>]
let main args =
    for arg in args do
        let newArg = PigLatin.toPigLatin arg
        printfn "%s in Pig Latin is: %s" arg newArg

    0

现在可以从命令行运行控制台应用:

dotnet run apple banana

你会看到,它输出的结果与脚本文件相同,但这次是作为正在运行的程序!

Ionide 故障排除

可以通过以下几种方法来解决你可能遇到的某些问题:

  1. 若要获取 Ionide 的代码编辑功能,需要将 F# 文件保存到磁盘,并将其保存到在 Visual Studio Code 工作区中打开的文件夹内。
  2. 如果在 Visual Studio Code 打开的情况下对系统进行了更改或安装了 Ionide 先决条件,请重启 Visual Studio Code。
  3. 如果项目目录中包含无效字符,则 Ionide 可能无法正常工作。 如果出现这种情况,请重命名项目目录。
  4. 如果所有 Ionide 命令都不起作用,请检查 Visual Studio Code 键绑定,以查看是否意外地替代了它们。
  5. 如果 Ionide 在计算机上遭到破坏,并且上述任何方法都无法解决问题,请尝试删除计算机上的 ionide-fsharp 目录,并重新安装该插件套件。
  6. 如果项目未能加载(F# 解决方案资源管理器会显示此内容),请右键单击该项目,然后单击“查看详细信息”以获取更多诊断信息。

Ionide 是由 F# 社区成员构建并维护的开放源代码项目。 请在 ionide-vscode-fsharp GitHub 存储库中报告问题并随意参与。

你还可以在 Ionide Gitter 频道中向 Ionide 开发人员和 F# 社区寻求进一步的帮助。

后续步骤

若要了解有关 F# 和该语言功能的详细信息,请参阅 F# 教程