Névterek (F#)
A névtér lehetővé teszi a kód rendszerezését a kapcsolódó funkciók területeire azáltal, hogy lehetővé teszi egy név csatolását az F#-programelemek csoportosításához. A névterek általában az F#-fájlok legfelső szintű elemei.
Syntax
namespace [rec] [parent-namespaces.]identifier
Megjegyzések
Ha egy névtérben szeretne kódot elhelyezni, a fájl első deklarációjának deklarálnia kell a névteret. A teljes fájl tartalma ezután a névtér részévé válik, feltéve, hogy a fájlban nincs más névtér-deklaráció. Ha ez a helyzet, akkor a következő névtér-deklarációig minden kód az utónévtéren belül van.
A névterek nem tartalmazhatnak közvetlenül értékeket és függvényeket. Ehelyett értékeket és függvényeket kell tartalmaznia a modulokban, a modulok pedig a névterekben. A névterek típusokat és modulokat tartalmazhatnak.
Az XML-dokumentum megjegyzései névtér felett deklarálhatók, de figyelmen kívül hagyják őket. A fordítói irányelvek névtér fölött is deklarálhatók.
A névterek explicit módon deklarálhatók a névtér kulcsszóval, vagy implicit módon egy modul deklarálásakor. Ha explicit módon szeretne névteret deklarálni, használja a névtér kulcsszót, majd a névtér nevét. Az alábbi példa egy kódfájlt mutat be, amely deklarál egy névteret Widgets
egy típussal és egy modullal a névtérben.
namespace Widgets
type MyWidget1 =
member this.WidgetName = "Widget1"
module WidgetsModule =
let widgetName = "Widget2"
Ha a fájl teljes tartalma egy modulban található, a kulcsszó használatával implicit módon is deklarálhatja a module
névtereket, és megadhatja az új névtérnevet a teljes modulnévben. Az alábbi példa egy olyan kódfájlt mutat be, amely egy névteret Widgets
és egy függvényt tartalmazó modult WidgetsModule
deklarál.
module Widgets.WidgetModule
let widgetFunction x y =
printfn "%A %A" x y
A következő kód egyenértékű az előző kóddal, de a modul egy helyi moduldeklaráció. Ebben az esetben a névtérnek a saját sorában kell megjelennie.
namespace Widgets
module WidgetModule =
let widgetFunction x y =
printfn "%A %A" x y
Ha több modulra van szükség ugyanabban a fájlban egy vagy több névtérben, helyi moduldeklarációkat kell használnia. Helyi moduldeklarációk használatakor nem használhatja a minősített névteret a moduldeklarációkban. Az alábbi kód egy névtérdeklarációval és két helyi moduldeklarációval rendelkező fájlt mutat be. Ebben az esetben a modulok közvetlenül a névtérben találhatók; nincs olyan implicit módon létrehozott modul, amelynek a neve megegyezik a fájl nevével. A fájl bármely más kódja, például egy do
kötés, a névtérben van, de nem a belső modulokban, ezért a modulnév használatával kell minősítenie a modul tagját 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
A példa kimenete a következő.
Module1 10 20
Module2 5 6
További információ: Modulok.
Beágyazott névterek
Beágyazott névtér létrehozásakor teljes mértékben jogosultnak kell lennie rá. Ellenkező esetben létrehoz egy új legfelső szintű névteret. A névtér deklarációi figyelmen kívül hagyják a behúzást.
Az alábbi példa bemutatja, hogyan deklarálhat beágyazott névteret.
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"
Névterek fájlokban és szerelvényekben
A névterek több fájlra is kiterjedhetnek egyetlen projektben vagy fordításban. A névtértöredék a névtér egy fájlban található részét írja le. A névterek több szerelvényre is kiterjedhetnek. A névtér például System
a teljes .NET-keretrendszer tartalmazza, amely számos szerelvényt foglal magában, és számos beágyazott névteret tartalmaz.
Globális névtér
Az előre definiált névtér global
használatával neveket helyezhet el a .NET legfelső szintű névterében.
namespace global
type SomeType() =
member this.SomeMember = 0
Globálisan is hivatkozhat a legfelső szintű .NET-névtérre, például a más névtérekkel való névütközések feloldásához.
global.System.Console.WriteLine("Hello World!")
Rekurzív névterek
A névterek rekurzívként is deklarálhatók, hogy az összes tartalmazott kód kölcsönösen rekurzív legyen. Ez a művelet a . használatával namespace rec
történik. namespace rec
A használat enyhítheti néhány fájdalmat, ha nem tud kölcsönösen hivatkozó kódot írni a típusok és modulok között. Az alábbiakban egy példa látható erre:
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
Vegye figyelembe, hogy a kivétel DontSqueezeTheBananaException
és az osztály Banana
egyaránt egymásra hivatkozik. Emellett a modul BananaHelpers
és az osztály Banana
is hivatkozik egymásra. Ez nem fejezhető ki F# nyelven, ha eltávolította a kulcsszót rec
a MutualReferences
névtérből.
Ez a funkció a legfelső szintű modulokhoz is elérhető.