F# 项目
在之前的几篇文章介绍的代码都在交互窗口(fsi.exe)里运行,但平常开发的软件程序可能含有大类类型和函数定义,代码不可能都在一个文件里。下面我们来看VS里提供的F#项目模板。
F#项目模板有以下几种类型(以VS2015为例):
Silverlight库创建Silverlight的类库
教程模板是一个控制台应用程序,里面包含了F#的示例,可通过这个项目快速了解F#相关内容。
“可移植库”则可创建用于多平台的库,支持的平台在括号里说明。
“库”用于创建类库
“控制台应用程序”大家就熟悉了。
安卓项目为安装了Xamarin创建的,请忽略。
我们创建一个控制台应用程序来说明,下图为程序的Program.fs
文件及运行结果:
我们添加一行代码(图中蓝框中)防止运行结束自动退出,这个应用程序默认是把参数打印出来,而运行时参数为空,所以结果为一空数组([||]
)。
其中ignore
函数用于丢弃System.Console.ReadKey()
结果。
现在项目中除了AssemblyInfo.fs
外,只有Program.fs
一个文件,下面我们先了解模块的相关信息再创建其他文件。
模块
模块简介
模块(Module)是F#程序代码的基本组织单位。默认情况下,每个F#代码文件(后缀为.fs
)对应一个模块,且必须在文件开头指定模块名称。
创建模块
我们创建File1.fs
文件时,默认会在开头添加module File1
,当然也可自己改成其他名称。
module File1let x = 1
在其他模块中使用File1.x
进行访问。
文件顺序
F#项目中的文件是有顺序要求的,在上面的文件无法访问下面的模块。我们可以使用Alt+上/下箭头进行调整文件顺序,或在文件上点击右键进行操作:
嵌套模块
模块中可嵌套模块,但定义内层模块需要在模块名后使用等号(=
),且内层模块的内容必须比它的上层模块缩进一级。
module TopLevelModel module NestedModule = //第一层嵌套模块
let i = 1
module NestedModuleInNestedModule = //第二层嵌套模块
let i = 2
使用模块
若想不使用模块名访问模块中的值时,则可使用open
关键字进行打开。但有两个需要注意的地方:
强制显示访问
在上一章介绍的集合模块中,我们从未使用open List
或者open Seq
这样的操作。
使用F12转到Seq
的代码定义文件可以发现Seq
模块使用了[<RequireQualifiedAccess>]
(强制显示访问)。
附加了此特性的模块在使用时必须使用模块名访问,因为几个集合模块中有大部分函数名称是相同的,若设置此特性而可同时打开了多个模块,则函数名称将会冲突。
自动打开
而我们在使用printfn
和ignore
函数时,均不需要打开相关模块,是因为在他们所属模块附加了[<AutoOpen>]
(自动打开