如何在Ubuntu 18.04上安装F#并设置本地编程环境

F#是一种简洁的开源函数编程语言,最初由Microsoft Research开发,用于扩展.NET,Microsoft的工具,库和语言集,以构建应用程序和服务。在本教程中,我们将使用.NET Core和Mono运行时在Ubuntu 18.04上设置F#编程环境。然后,我们将编写一些代码示例来测试和查看构建和编译方法。

作者选择自由软件基金会作为Write for DOnations计划的一部分接受捐赠。

介绍

F#是一种开源编程语言,最初由Microsoft Research开发,用于扩展.NET ,Microsoft的工具,库和语言集,以构建应用程序和服务。 除了非常简洁的语法之外,F#还支持多种范例 ,这意味着它可以执行不同类型的代码结构,尽管它主要是为了利用函数式编程方法而设计的。

采用特定的范例或代码风格决定了我们思考和组织编程问题的方式。 使用命令式方法 ,在C ++Java等语言中使用的设计模型,开发人员逐步描述计算机必须如何完成任务。 它是关于编写一系列语句,这些语句将在程序执行时改变内存状态。 这种方法很好,直到遇到一些不规则的情况。 例如,考虑一个共享对象 ,它由多个应用程序同时使用。 我们可能希望在另一个组件正在修改它的同时读取它的值。 这些是对内存位置的并发操作 ,可能会产生数据不一致和未定义的行为。

功能代码设计中 ,我们通过最小化可变状态的使用或在我们制作之后可以改变的状态来防止这种问题。 函数是这里的关键字,指的是作为参数提供的一些信息的数学变换。 功能代码通过将解决方案组合为要执行的一组功能来表示程序是什么。 通常,我们使用可以返回另一个函数或将其他函数作为输入的函数来构建逻辑层。

使用F#进行功能编程带来了许多好处:

  • 更具可读性和表现力的语法,可提高程序的可维护性。
  • 由于无状态函数可以隔离进行测试,因此代码不易破解且易于调试。
  • 本机构造有助于异步编程和更安全的并发。
  • 访问.NET世界中的所有现有工具,包括社区共享包。

选择运行时

由于F#是跨平台的,因此通过不同的操作系统维护类似的执行模型行为至关重要。 .NET通过运行时实现了这一点。 运行时系统是一个软件,它协调用特定编程语言编写的程序的执行,处理与操作系统和存储器管理的接口等。

实际上Linux上有两种.NET运行时实现: .NET CoreMono 从历史上看,.NET仅适用于Windows。 在那些日子里,人们可以求助于社区Mono项目在Linux和macOS等其他平台上运行.NET应用程序。 微软随后推出了.NET Core,它是原始.NET框架的一个更快的模块化子集,目标是多个平台。

在本教程发布时,它们都可用于构建Web应用程序或命令行实用程序。 也就是说,.NET Core不提供模型来在Linux和macOS上创建GUI桌面应用程序,而Mono是唯一支持移动和游戏平台的应用程序。 了解这些差异非常重要,因为您选择的运行时将决定您将构建的程序。 您还可以选择同时安装.NET Core和Mono,以便考虑所有用例并提高效率。

在本教程中,您将使用.NET Core和Mono运行时在Ubuntu 18.04上设置F#编程环境。 然后,您将编写一些代码示例来测试和查看构建和编译方法。

先决条件

要完成本教程,您将需要基本熟悉命令行和运行Ubuntu 18.04的计算机以及具有sudo权限非root用户

第1步 - 使用.NET Core安装F#

Microsoft为F#开发人员提供.NET核心软件开发工具包(SDK) 软件开发工具包是一组编程工具,允许程序员生成专门的应用程序并使其适应各种操作系统。 它传统上包括文本编辑器,语言支持,运行时和编译器等。 在此步骤中,您将安装此SDK。 但首先,您将注册Microsoft存储库并获取一些依赖项。

您将在命令行上完成安装和设置,这是一种与计算机交互的非图形方式。 也就是说,您不是单击按钮,而是键入文本并通过文本从计算机接收反馈。

命令行(也称为shell终端 )可以帮助修改和自动化您每天在计算机上执行的许多任务,并且是软件开发人员必不可少的工具。 有许多终端命令需要学习,可以让你做更强大的事情。 有关命令行的更多信息,请查看Linux Terminal简介教程。

在Ubuntu 18.04上,您可以通过单击屏幕左上角的Ubuntu图标并在搜索栏中键入terminal来找到终端应用程序。 单击终端应用程序图标将其打开。 或者,您可以同时按下键盘上的CTRLALTT键以自动打开终端应用程序。

Ubuntu终端

打开终端后,使用wget命令下载包含一些必需文件的包,Microsoft存储库配置以及用于服务器通信的密钥。

wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb

现在,添加Microsoft存储库并使用dpkg -i指令将软件包安装到系统中。

sudo dpkg -i packages-microsoft-prod.deb

接下来,激活Universe存储库,Ubuntu是一个社区维护的免费和开源软件存档。 这将使您可以访问apt-transport-https ,这是通过HTTPS启用Ubuntu包管理器APT传输的依赖项。

sudo add-apt-repository universe
sudo apt install apt-transport-https

接下来,更新可用下载:

sudo apt update

最后,安装当前版本的.NET SDK。 本教程将使用2.2版:

sudo apt install dotnet-sdk-2.2

现在您已经安装了.NET SDK,快速检查一切是否顺利的方法是尝试.NET Core命令行界面(CLI),一旦下载并安装SDK,它将在shell中可用。 在终端中输入以下内容,显示有关.NET设置的信息:

dotnet --info

当您第一次运行dotnet命令时,将显示一个文本部分,如下所示:

Welcome to .NET Core!
---------------------
Learn more about .NET Core: https://aka.ms/dotnet-docs
Use 'dotnet --help' to see available commands or visit: https://aka.ms/dotnet-cli-docs

Telemetry
---------
The .NET Core tools collect usage data in order to help us improve your experience. The data is anonymous and doesn't include command-line arguments. The data is collected by Microsoft and shared with the community. You can opt-out of telemetry by setting the DOTNET_CLI_TELEMETRY_OPTOUT environment variable to '1' or 'true' using your favorite shell.

Read more about .NET Core CLI Tools telemetry: https://aka.ms/dotnet-cli-telemetry
...

此通知与收集的数据有关,并说明某些.NET CLI命令会将使用信息发送给Microsoft。 你马上就会禁用它; 现在,看看dotnet --info的输出。

片刻之后,终端将列出有关.NET安装的信息:

.NET Core SDK (reflecting any global.json):
 Version:   2.2.101
 Commit:    236713b0b7

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  18.04
 OS Platform: Linux
 RID:         ubuntu.18.04-x64
 Base Path:   /usr/share/dotnet/sdk/2.2.101/

Host (useful for support):
  Version: 2.2.0
  Commit:  1249f08fed

.NET Core SDKs installed:
  2.2.101 [/usr/share/dotnet/sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.2.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.2.0 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.2.0 [/usr/share/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download

根据SDK版本,输出可能略有不同,但这确认.NET Core已准备好使用。

如前所述,遥测功能允许某些.NET CLI命令将使用信息发送给Microsoft。 它默认启用,可以通过将DOTNET\_CLI\_TELEMETRY_OPTOUT环境变量设置为1来取消激活。 为此,请在.profile环境自定义文件中添加一个新行,方法是在文本编辑器中打开它。 对于本教程,我们将使用nano

nano ~/.profile

.profile下行添加到.profile的末尾:

〜/ .profile文件
. . .
export DOTNET_CLI_TELEMETRY_OPTOUT=1

CTRLX键退出nano 提示保存文件时,按Y然后按ENTER

您可以使用source命令激活新配置:

source ~/.profile

从现在开始,遥测将在启动时关闭。

此时,您已安装.NET Core运行时,语言支持和库,允许您运行和构建一些.NET应用程序。 dotnet CLI也可用于管理.NET源代码和二进制文件。 您可以开始构建F#项目,但如前所述,.NET Core环境不提供完全跨平台所需的所有构造。 例如,目前您无法使用它来开发移动应用程序。

为了解决这个问题,在下一步中你将再次安装F#,但这次使用的是Mono。

第2步 - 使用Mono安装F#

您可以使用Mono来填补.NET Core留下的剩余功能空白。 Mono和.NET Core都基于相同的标准库,并且都支持.NET语言,但这就是相似性的结束。 它们使用不同的运行时,不同的CLI和不同的编译器,使它们可以并排安装,以创建更可靠的编程环境。 在本节中,您将使用用于.NET编程的Mono工具来补充您的环境,并从命令行运行F#程序。

Ubuntu存储库中提供了Mono的一个版本,但这可能已经过时了。 而是将官方Mono包存储库添加到包管理器:

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb https://download.mono-project.com/repo/ubuntu stable-bionic main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list

在前面的命令中,您使用了apt-key来检索用于保护从官方Mono存储库传输的包的密钥。 然后,您将Mono包源添加到存储库列表中。

为APT添加新的源列表,更新您的存储库:

sudo apt update

接下来,下载Mono工具。 与.NET Core不同,Mono不包含F#工具,因此您将其作为单独的包下载。 使用以下命令安装fsharpmono-complete元软件包:

sudo apt install mono-complete fsharp

注意:由于此下载的大小, mono-complete的安装过程可能需要一段时间。

完成后,您将拥有编译器fsharpc和一个名为fsharpi或简称FSI的交互式shell。 FSI是shell内部的一个环境,它接收用户的输入作为表达式,对其进行评估,然后输出结果并等待另一个输入。 就像在传统shell中键入命令并查看结果一样,除了这里,输入是F#表达式。 FSI提供了一种快速测试代码或运行脚本的方法。

使用以下命令激活FSI:

fsharpi

这将启动交互式会话并使用fsharpi提示替换常规提示:

Microsoft (R) F# Interactive version 4.1
Copyright (c) Microsoft Corporation. All Rights Reserved.

For help type #help;;

>

您可以通过运行#quit;;返回默认shell。 fsharpi ,每个命令行以双分号结束。

让我们尝试使用printfn函数进行简单操作,以呈现作为参数传递的消息:

printfn "Hello World!";;

您将收到以下输出:

Hello World!
val it : unit = ()

> 

从前面的交互中, fsharpi将表达式计算为unit类型值。 然后执行代码并使用其类型打印结果。

fsharpi还可以运行包含F#代码的文件。 该脚本必须以.fsx扩展名命名,并使用以下命令从shell执行:

fsharpi some_script.fsx

既然您知道F#安装正在运行,请保留shell:

> #quit;;

安装了Mono和.NET Core后,您现在可以编写任何类型的F#程序。 如果需要,FSI将允许您测试代码并运行一些脚本,但执行速度会很慢。 为了执行您的F#脚本,需要执行其他步骤将源代码转换为处理器可理解的工件,因此速度很慢。 为了解决这个问题,在下一节中,您将使用.NET Core编译代码,创建可由机器立即运行的独立二进制文件。

第3步 - 使用.NET Core编写和编译F#程序

在此步骤中,您将通过.NET Core提供的命令行编译器编译F#源代码。 这将使您的应用程序更快,并为特定系统生成预设的可执行程序包,使您的程序更容易分发。

编译是将源代码转换为二进制文件的转换过程。 完成此转换的软件称为编译器。 .NET Core依赖于dotnet CLI来执行编译。 为了演示这一点,您将创建一个基本的F#源来查看编译案例。

dotnet CLI提供了完整的应用程序构建工具链。 通常,在shell中使用命令和dotnet驱动程序的关联来完成任务。 例如:

  • dotnet new将创建一个项目
  • dotnet build将构建一个项目及其所有依赖项
  • dotnet add package将添加对项目文件的包引用

以下将创建一个名为FSharpHello的新控制台项目。 -lang选项设置要编码的编程语言,而-o选项创建用于放置输出的目录。

dotnet new console -lang F# -o FSharpHello

完成后,导航到新创建的项目目录:

cd FSharpHello

该目录包含FSharpHello .fsproj项目配置文件和用于存储临时目标文件的obj文件夹。 还有Program.fs文件,其中存在您的默认源代码。 在文本编辑器中打开它:

nano Program.fs

该文件已自动填充Hello World程序:

Program.fs
// Learn more about F# at http://fsharp.org

open System

[<EntryPoint>]
let main argv =
    printfn "Hello World from F#!"
    0 // return an integer exit code

在此代码中,您开始使用open System导入System模块,然后定义程序入口点,即从shell启动时程序启动的位置。 main函数将调用Hello World消息打印到控制台并将停止程序( return an integer exit code )。

退出文件。

要编译和运行此代码,请使用项目目录~/ FSharpHello的以下~/ FSharpHello

dotnet run

程序将运行,将以下输出打印到屏幕:

Hello World from F#!

请注意,此程序运行需要一段时间,就像使用FSI一样。 正如我们之前提到的,通过生成可执行文件,即可以由操作系统直接运行的二进制文件,可以更快地运行它。 以下是如何实现这一目标:

dotnet publish -c release -r linux-x64

这将生成可执行文件bin/release/netcoreapp 2.2 /linux-x64/publish/ FSharpHello .dll文件。 这是一个可在64位Linux体系结构上运行的共享库。 要导出macOS系统的通用可执行文件,您可以使用osx-x64替换linux-x64运行时标识符( RID )。

现在使用以下命令执行该文件:

dotnet bin/release/netcoreapp2.2/linux-x64/publish/FSharpHello.dll

这次,您将更快地收到输出,因为该程序已经被翻译成二进制文件。

既然您已经知道如何在.NET Core中编译,那么让我们看看Mono如何使用专用的fsharpc命令编译程序。

第4步 - 使用Mono编写和编译F#程序

Mono的编译过程类似于.NET Core,但这次有一个特定的命令用于编译程序。 fsharpc命令是工具,它仅为编译而创建。

这次,创建一个hello.fs文件并编写一些F#代码。 首先,返回您的主目录:

cd

接下来,打开一个名为hello.fs的新文件:

nano hello.fs

将以下行添加到文件中:

hello.fs
open System

如前所述,这将导入System模块或命名空间,使您可以访问内置系统功能和Console等对象。

现在,添加更多代码行:

hello.fs
open System

let hello() =
    printf "Who are you? "
    let name = Console.ReadLine()
    printfn "Oh, Hello %s!\nI'm F#." name

这些新行定义了hello()函数来读取用户输入并打印反馈消息。

现在您可以添加最后一行:

hello.fs
open System

let hello() =
    printf "Who are you? "
    let name = Console.ReadLine()
    printfn "Oh, Hello %s!\nI'm F#." name

hello()
Console.ReadKey() |> ignore

在这里,您调用函数hello() ,然后使用ReadKey()方法以最终击键结束程序。

保存并退出该文件。

现在使用fsharpc命令,使用-o标志来定义输出文件名并编译hello.fs源代码,如下所示:

fsharpc hello.fs -o hello

上面的命令将生成一个可以使用mono命令运行的hello可执行文件:

mono hello

这将为您提供以下输出并等待用户输入:

Who are you?

如果您输入Sammy ,您将获得以下信息。

Oh, Hello Sammy!
I'm F#.

按下最后一次击键,程序将结束。

恭喜! 您已经编写并编译了第一个F#程序,包括Mono和.NET Core。

结论

在本教程中,您安装了用于F#编程的工具,涵盖.NET Core和Mono环境。 您还测试了F#代码和构建可执行文件的示例。 这是学习这种实用功能语言的第一步。

接下来的步骤可能是学习 语言并与社区联系 此外,随着项目变得越来越复杂,您可能需要更有效地管理代码和资源。 NuGetPaket这样的软件包管理器是构建围绕.NET构建的强大生态系统的桥梁,也是组织大型程序的首选工具。