Naamruimten (F#)

Met een naamruimte kunt u code ordenen in gebieden met gerelateerde functionaliteit door u in staat te stellen een naam toe te voegen aan een groep F#-programma-elementen. Naamruimten zijn meestal elementen op het hoogste niveau in F#-bestanden.

Syntaxis

namespace [rec] [parent-namespaces.]identifier

Opmerkingen

Als u code in een naamruimte wilt plaatsen, moet de eerste declaratie in het bestand de naamruimte declareren. De inhoud van het hele bestand wordt vervolgens onderdeel van de naamruimte, mits er verder geen andere naamruimtendeclaratie aanwezig is in het bestand. Als dat het geval is, wordt alle code tot de volgende naamruimtedeclaratie beschouwd als binnen de eerste naamruimte.

Naamruimten kunnen geen waarden en functies rechtstreeks bevatten. In plaats daarvan moeten waarden en functies worden opgenomen in modules en modules worden opgenomen in naamruimten. Naamruimten kunnen typen en modules bevatten.

Opmerkingen bij XML-documenten kunnen worden gedeclareerd boven een naamruimte, maar worden genegeerd. Compiler-instructies kunnen ook worden gedeclareerd boven een naamruimte.

Naamruimten kunnen expliciet worden gedeclareerd met het trefwoord voor de naamruimte of impliciet bij het declareren van een module. Als u een naamruimte expliciet wilt declareren, gebruikt u het naamruimtewoord gevolgd door de naamruimtenaam. In het volgende voorbeeld ziet u een codebestand dat een naamruimte Widgets declareert met een type en een module die is opgenomen in die naamruimte.

namespace Widgets

type MyWidget1 =
    member this.WidgetName = "Widget1"

module WidgetsModule =
    let widgetName = "Widget2"

Als de volledige inhoud van het bestand zich in één module bevindt, kunt u ook impliciet naamruimten declareren met behulp van het module trefwoord en de nieuwe naamruimtenaam opgeven in de volledig gekwalificeerde modulenaam. In het volgende voorbeeld ziet u een codebestand dat een naamruimte Widgets en een module WidgetsModuledeclareert, die een functie bevat.

module Widgets.WidgetModule

let widgetFunction x y =
   printfn "%A %A" x y

De volgende code is gelijk aan de voorgaande code, maar de module is een lokale moduledeclaratie. In dat geval moet de naamruimte op een eigen regel worden weergegeven.

namespace Widgets

module WidgetModule =

    let widgetFunction x y =
        printfn "%A %A" x y

Als meer dan één module vereist is in hetzelfde bestand in een of meer naamruimten, moet u lokale moduledeclaraties gebruiken. Wanneer u lokale moduledeclaraties gebruikt, kunt u de gekwalificeerde naamruimte niet gebruiken in de moduledeclaraties. De volgende code toont een bestand met een naamruimtedeclaratie en twee lokale moduledeclaraties. In dit geval bevinden de modules zich rechtstreeks in de naamruimte; er is geen impliciet gemaakte module met dezelfde naam als het bestand. Alle andere code in het bestand, zoals een do binding, bevindt zich in de naamruimte, maar niet in de binnenste modules, dus moet u het modulelid widgetFunction kwalificeren met behulp van de modulenaam.

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

De uitvoer van dit voorbeeld is als volgt.

Module1 10 20
Module2 5 6

Zie Modules voor meer informatie.

Geneste naamruimten

Wanneer u een geneste naamruimte maakt, moet u deze volledig kwalificeren. Anders maakt u een nieuwe naamruimte op het hoogste niveau. Inspringing wordt genegeerd in naamruimtedeclaraties.

In het volgende voorbeeld ziet u hoe u een geneste naamruimte declareert.

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"

Naamruimten in bestanden en assembly's

Naamruimten kunnen meerdere bestanden in één project of compilatie omvatten. In het fragment van de termnaamruimte wordt het deel van een naamruimte beschreven dat in één bestand is opgenomen. Naamruimten kunnen ook meerdere assembly's omvatten. De naamruimte bevat bijvoorbeeld System het hele .NET Framework, dat veel assembly's omvat en veel geneste naamruimten bevat.

Globale naamruimte

U gebruikt de vooraf gedefinieerde naamruimte global om namen in de .NET-naamruimte op het hoogste niveau te plaatsen.

namespace global

type SomeType() =
    member this.SomeMember = 0

U kunt ook globaal gebruiken om te verwijzen naar de .NET-naamruimte op het hoogste niveau, bijvoorbeeld om naamconflicten met andere naamruimten op te lossen.

global.System.Console.WriteLine("Hello World!")

Recursieve naamruimten

Naamruimten kunnen ook worden gedeclareerd als recursief, zodat alle ingesloten code wederzijds recursief kan zijn. Dit gebeurt via namespace rec. Het gebruik van namespace rec kan sommige pijn verlichten bij het niet kunnen schrijven van wederzijds referentiële code tussen typen en modules. Hier volgt een voorbeeld van:

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 (b: Banana) =
        let flip (banana: Banana) =
            match banana.Orientation with
            | Up ->
                banana.Orientation <- Down
                banana
            | Down -> banana

        let peelSides (banana: Banana) =
            banana.Sides
            |> List.map (function
                         | Unpeeled -> Peeled
                         | Peeled -> Peeled)

        match b.Orientation with
        | Up ->   b |> flip |> peelSides
        | Down -> b |> peelSides

Houd er rekening mee dat de uitzondering DontSqueezeTheBananaException en de klasse Banana beide naar elkaar verwijzen. Daarnaast verwijzen de module BananaHelpers en de klasse Banana ook naar elkaar. Dit zou niet mogelijk zijn om in F# uit te drukken als u het rec trefwoord uit de MutualReferences naamruimte hebt verwijderd.

Deze functie is ook beschikbaar voor modules op het hoogste niveau.

Zie ook