名前空間を使用すると、F# プログラム要素のグループに名前を添付できるようにすることで、関連する機能の領域にコードを整理できます。 名前空間は通常、F# ファイルの最上位要素です。
構文
namespace [rec] [parent-namespaces.]identifier
注釈
コードを名前空間に配置する場合は、ファイル内の最初の宣言で名前空間を宣言する必要があります。 その後、ファイル全体の内容が名前空間の一部になります。ただし、他の名前空間宣言がファイル内にそれ以上存在しない場合。 その場合、次の名前空間宣言までのすべてのコードは、最初の名前空間内にあると見なされます。
名前空間には、値と関数を直接含めることはできません。 代わりに、値と関数をモジュールに含める必要があり、モジュールは名前空間に含まれます。 名前空間には、型とモジュールを含めることができます。
XML ドキュメント コメントは名前空間の上に宣言できますが、無視されます。 コンパイラ ディレクティブは、名前空間の上に宣言することもできます。
名前空間は、名前空間キーワードを使用して明示的に宣言することも、モジュールを宣言するときに暗黙的に宣言することもできます。 名前空間を明示的に宣言するには、名前空間キーワードの後に名前空間名を付けます。 次の例は、型とその名前空間に含まれるモジュールを使用して名前空間 Widgets
を宣言するコード ファイルを示しています。
namespace Widgets
type MyWidget1 =
member this.WidgetName = "Widget1"
module WidgetsModule =
let widgetName = "Widget2"
ファイルの内容全体が 1 つのモジュールにある場合は、 module
キーワードを使用し、完全修飾モジュール名に新しい名前空間名を指定することで、名前空間を暗黙的に宣言することもできます。 次の例は、名前空間 Widgets
を宣言するコード ファイルと、関数を含むモジュール WidgetsModule
を示しています。
module Widgets.WidgetModule
let widgetFunction x y =
printfn "%A %A" x y
次のコードは上記のコードと同じですが、モジュールはローカル モジュール宣言です。 その場合、名前空間は独自の行に表示する必要があります。
namespace Widgets
module WidgetModule =
let widgetFunction x y =
printfn "%A %A" x y
1 つ以上の名前空間の同じファイルに複数のモジュールが必要な場合は、ローカル モジュール宣言を使用する必要があります。 ローカル モジュール宣言を使用する場合、モジュール宣言で修飾された名前空間を使用することはできません。 次のコードは、名前空間宣言と 2 つのローカル モジュール宣言を持つファイルを示しています。 この場合、モジュールは名前空間に直接含まれます。ファイルと同じ名前の暗黙的に作成されたモジュールはありません。
do
バインディングなど、ファイル内の他のコードは名前空間内にありますが、内部モジュールには含まれていないため、モジュール名を使用してモジュール メンバーwidgetFunction
を修飾する必要があります。
namespace Widgets
module WidgetModule1 =
let widgetFunction x y =
printfn "Module1 %A %A" x y
module WidgetModule2 =
let widgetFunction x y =
printfn "Module2 %A %A" x y
module useWidgets =
do
WidgetModule1.widgetFunction 10 20
WidgetModule2.widgetFunction 5 6
この例の出力は次のとおりです。
Module1 10 20
Module2 5 6
詳細については、「モジュールの」を参照してください。
入れ子になった名前空間
入れ子になった名前空間を作成するときは、完全に修飾する必要があります。 それ以外の場合は、新しい最上位レベルの名前空間を作成します。 名前空間宣言ではインデントは無視されます。
次の例は、入れ子になった名前空間を宣言する方法を示しています。
namespace Outer
// Full name: Outer.MyClass
type MyClass() =
member this.X(x) = x + 1
// Fully qualify any nested namespaces.
namespace Outer.Inner
// Full name: Outer.Inner.MyClass
type MyClass() =
member this.Prop1 = "X"
ファイルとアセンブリの名前空間
名前空間は、1 つのプロジェクトまたはコンパイルで複数のファイルにまたがることができます。
名前空間フラグメントという用語は、1 つのファイルに含まれる名前空間の部分を表します。 名前空間は、複数のアセンブリにまたがることもできます。 たとえば、 System
名前空間には.NET Framework 全体が含まれており、これは多数のアセンブリにまたがるため、入れ子になった名前空間が多数含まれています。
グローバル名前空間
定義済みの名前空間 global
を使用して、.NET の最上位の名前空間に名前を配置します。
namespace global
type SomeType() =
member this.SomeMember = 0
グローバルを使用して最上位レベルの .NET 名前空間を参照することもできます。たとえば、他の名前空間との名前の競合を解決できます。
global.System.Console.WriteLine("Hello World!")
再帰的な名前空間
名前空間は再帰的として宣言して、含まれるすべてのコードを相互に再帰的にできるようにすることもできます。 これは、 namespace rec
を介して行われます。
namespace rec
を使用すると、型とモジュールの間で相互参照コードを記述できないといういくつかの問題を軽減できます。 この例を次に示します。
namespace rec MutualReferences
type Orientation = Up | Down
type PeelState = Peeled | Unpeeled
// This exception depends on the type below.
exception DontSqueezeTheBananaException of Banana
type Banana(orientation: Orientation) =
member val IsPeeled = false with get, set
member val Orientation = orientation with get, set
member val Sides: PeelState list = [Unpeeled; Unpeeled; Unpeeled; Unpeeled] with get, set
member self.Peel() = BananaHelpers.peel self // Note the dependency on the BananaHelpers module.
member self.SqueezeJuiceOut() = raise (DontSqueezeTheBananaException self) // This member depends on the exception above.
module BananaHelpers =
let peel (banana: Banana) =
let flip (banana: Banana) =
match banana.Orientation with
| Up ->
banana.Orientation <- Down
banana
| Down -> banana
// Update the peel state for all sides of the banana.
let peelSides (banana: Banana) =
banana.Sides
|> List.map (function
| Unpeeled -> Peeled
| Peeled -> Peeled)
// Apply the flipping and peeling logic based on the orientation.
match banana.Orientation with
| Up -> banana |> flip |> peelSides
| Down -> banana |> peelSides
例外 DontSqueezeTheBananaException
とクラス Banana
両方が相互に参照されることに注意してください。 さらに、モジュール BananaHelpers
とクラス Banana
も相互に参照します。
MutualReferences
名前空間から rec
キーワードを削除した場合、F# ではこれを表すことはできません。
この機能は、最上位レベルの モジュールでも使用できます。
こちらも参照ください
.NET