模組 (F#)
在 F# 語言的內容中,「模組」(Module) 是 F# 程式碼群組,例如 F# 程式中的值、型別和函式值。 將程式碼分組成不同模組有助於將相關程式碼整理在同一處,以及避免程式中發生名稱衝突。
// Top-level module declaration.
module [accessibility-modifier] [qualified-namespace.]module-name
declarations
// Local module declaration.
module [accessibility-modifier] module-name =
declarations
備註
F# 模組是 F# 程式碼建構群組,例如型別、值、函式值,以及 do 繫結中的程式碼。 它會實作為只有靜態成員的 Common Language Runtime (CLR) 類別。 根據整個檔案是否包含在模組中,有兩種模組宣告:最上層模組宣告和區域模組宣告。 最上層模組宣告將整個檔案包含在模組中, 而且只能顯示為檔案中的第一個宣告。
在最上層模組宣告的語法中,選擇性 qualified-namespace 是包含模組的巢狀命名空間名稱序列。 限定命名空間先前不需要宣告。
您不必縮排最上層模組中的宣告, 但必須縮排區域模組中的所有宣告。 在區域模組宣告中,只有在該模組宣告底下縮排的宣告才是模組的一部分。
如果程式碼檔不是以最上層模組宣告或命名空間宣告開始,該檔案的整個內容 (包含任何區域模組) 會成為隱含建立之最上層模組 (其名稱與檔案名稱相同但不含副檔名,而且第一個字母轉換為大寫字) 的一部分。 例如,假設有下列檔案。
// In the file program.fs.
let x = 40
這個檔案會像是以下列方式撰寫一樣來編譯:
module Program
let x = 40
如果檔案中有多個模組,您必須為每個模組使用一個區域模組宣告。 如果宣告封入命名空間,這些模組就會是此封入命名空間的一部分。 如果未宣告封入命名空間,這些模組就會成為隱含建立之最上層模組的一部分。 在下列程式碼範例中,會示範包含多個模組的程式碼檔。 編譯器會隱含建立名為 Multiplemodules 的最上層模組,而且 MyModule1 和 MyModule2 會巢狀置於該最上層模組中。
// In the file multiplemodules.fs.
// MyModule1
module MyModule1 =
// Indent all program elements within modules that are declared with an equal sign.
let module1Value = 100
let module1Function x =
x + 10
// MyModule2
module MyModule2 =
let module2Value = 121
// Use a qualified name to access the function.
// from MyModule1.
let module2Function x =
x * (MyModule1.module1Function module2Value)
如果您的專案或單一編譯中有多個檔案,或是您建置的是程式庫,則必須在檔案頂端加入命名空間宣告或模組宣告。 只有在專案或編譯命令列中只有一個檔案,而且您建立的是應用程式時,F# 編譯器才會隱含地判斷模組名稱。
accessibility-modifier 可以是下列其中一項:public、private、internal。 如需詳細資訊,請參閱存取控制 (F#)。 預設值為 public。
參考模組中的程式碼
當您參考來自另一個模組的函式、型別和值時,必須使用限定名稱或開啟該模組。 如果使用限定名稱,您必須指定命名空間、模組,以及所需程式項目的識別項。 您可以用點 (.) 分隔限定路徑的每個部分,如下所示。
Namespace1.Namespace2.ModuleName.Identifier
您可以開啟模組或一個或多個命名空間,以簡化程式碼。 如需開啟命名空間和模組的詳細資訊,請參閱匯入宣告:open 關鍵字 (F#)。
在下列程式碼範例中,會示範包含所有程式碼直到檔案結尾的最上層模組。
module Arithmetic
let add x y =
x + y
let sub x y =
x - y
若要從相同專案的另一個檔案使用此程式碼,您可以使用限定名稱或在使用函式前開啟模組,如下列範例所示。
// Fully qualify the function name.
let result1 = Arithmetic.add 5 9
// Open the module.
open Arithmetic
let result2 = add 5 9
巢狀模組
模組可以是巢狀結構。 內部模組的縮排距離必須與外部模組宣告相同,表示它們是內部模組,而不是新模組。 例如,比較下列兩個範例。 在下列程式碼中,模組 Z 是內部模組。
module Y =
let x = 1
module Z =
let z = 5
但是在下列程式碼中,模組 Z 與模組 Y 位於同層級。
module Y =
let x = 1
module Z =
let z = 5
在下列程式碼中,模組 Z 也是同層級模組,因為它的縮排距離不如模組 Y 中的其他宣告。
module Y =
let x = 1
module Z =
let z = 5
最後,如果外部模組沒有宣告,而且後面緊接著另一個模組宣告,則會假設新模組宣告為內部模組,但是如果第二個模組宣告的縮排距離不如第一個,編譯器會顯示警告。
// This code produces a warning, but treats Z as a inner module.
module Y =
module Z =
let z = 5
若要排除警告,請縮排內部模組。
module Y =
module Z =
let z = 5
如果您要檔案中的所有程式碼都是在單一外部模組中,同時也要內部模組時,此外部模組不需要等號,而且將放在外部模組中的宣告 (包含任何內部模組宣告) 不必縮排。 在內部模組宣告中的宣告不必縮排。 下列程式碼會示範這個案例。
// The top-level module declaration can be omitted if the file is named
// TopLevel.fs or topLevel.fs, and the file is the only file in an
// application.
module TopLevel
let topLevelX = 5
module Inner1 =
let inner1X = 1
module Inner2 =
let inner2X = 5