■ 模塊
模塊是指將定義進行統一彙總並賦予名稱的功能。由於只將有關聯的定義進行統一彙總,所以可以提高代碼塊的獨立性。雖然F#中的模塊體系是從Ocaml中轉變而來的,但是與Ocaml不同的是:
1.Functor等的一部分沒有被封裝進來
2.模塊名可以是大寫字母,也可以是小寫字母
模塊的定義可以用F#版或Ocaml版的兩種方式進行定義。
- F#版的模塊定義
- 模塊定義:= begin [模塊元素]* end
模塊元素:=
| let表達式
| type定義
| 異常定義
| 子模塊定義
| 子模塊的省略名稱的定義
| import聲明
子模塊的省略名稱的定義:=
module 省略名稱 = 模塊名
- Ocaml兼容版的模塊定義
- 模塊定義:= struct [模塊元素]* end
(其他部分與上相同)
另外,加上#light語句的時候可以省略begin,end。
接下來,讓我們看實際的模塊的例子。
//最小的模塊。模塊名可以爲小寫字母 module a = begin end;; |
上例中定義了a,b,c三個模塊。訪問模塊中定義好的元素時需要象上例中那樣加上點符號。
//類型的定義。模塊名當然可以爲大寫字母 |
上例爲定義類型,異常,省略名稱的例子.
接下來,可以定義複合模塊.
module Mix = begin |
同時,模塊可以嵌套。
module A = begin |
對於模塊,雖然進行訪問時必須加上點符號,但是在比較麻煩的時候,可以對模塊進行open。
module A = begin |
在上例中定義了模塊A,由於對A模塊進行了open,所以訪問A模塊中的a元素時可以不加點符號。
接下來,可以在模塊中直接使用open,這種情況下,模塊內的open不會影響到模塊之外。
module A = begin |
一般,不針對List模塊進行open,但是,在模塊A內部即使對List進行了open操作,也不會對模塊外產生任何影響,這種方法是可以使用的。
更進一步來說,可以給模塊添加自動open的AutoOpen屬性(Microsoft.FSharp.Core.AutoOpenAttribute)。下例中將模塊進行嵌套並執行AutoOpen。
#light "off" |
可以確認加了AutoOpen屬性的模塊在被訪問時可以不加模塊名而直接訪問。
■ 命名空間
當程序的規模大到一定程度時,會產生函數或變量名互相沖突的問題。爲了解決這類問題,可以考慮使用命名空間。在.Net中定義了各種類庫,定義了不同語言的Microsoft.FSharp,Microsoft.CSharp,Microsoft.VisualBasic等很多命名空間。
命名空間的定義形式基本如下:
- 命名空間的定義
- 封裝文件:= [命名空間的定義]*
命名空間的定義:=
| namespace 命名空間名 頂級模塊的定義
| module 模塊名 模塊的元素
| 模塊的元素
舉例如下
namespace test |
這個例子中定義了命名空間test與其中的模塊A。
同樣也可以對命名空間進行open。
//file1.fs |
在這個例子中,在file1.fs文件中定義了命名空間test並在main.fs文件中對test命名空間進行open。另外,應該要注意的是,如果首先編譯了main.fs文件,則對file1.fs文件中的命名空間進行的open操作就不能正常執行了。關於這一點,請參考編譯器的使用方法一節中的程序裝載順序部分。
使用命名空間時,與使用模塊不同的是:
1.不能在定義命名空間的時候定義值(let等等)。
2.不能在命名空間的定義前書寫針對編譯器進行的指示代碼。
3.由於上述因素,不能對命名空間進行AutoOpen。
4.命名空間不能被嵌套。
5.命名空間沒有省略名稱。
針對前面命名空間部分中的第一個例子,以下寫法會引起編譯錯誤。
namespace A |
另外如前所述,命名空間不能被嵌套使用。雖然默認打開的命名空間(後文詳述)表面上看上去像是嵌套空間,但實際上是通過如下方式被打開的。
namespace N |
上例中的定義可以被象下例中所示地分階段打開。但是,1.9.6.2版本後不推薦這種打開方式。
open N; |
這是因爲,在F#中,原本是允許如下所示的打開方法的,但是現在推薦使用命名空間的完全名稱的打開方式。
open System |
另外,在命名空間的定義部分的第2,3行中的函數分別被稱爲具名函數/匿名函數.因此,可以象下例那樣不加begin/end語句而直接定義模塊.
module A |
另外,迄今爲止沒有定義模塊而直接書寫的代碼都在匿名模塊中,這一點請注意.
最後,介紹默認打開的命名空間.包括F#在內的所有.Net開發語言都自動引用mscorlib.dll,F#更進一步地自動引用了FSharp.Core.dll.由於引用了該dll,F#程序執行時自動打開以下這些命名空間。
open Microsoft.FSharp |