Пространства имен (F#)
Пространство имен позволяет упорядочивать код в области связанных функциональных возможностей, позволяя прикрепить имя к группировке элементов программы F#. Пространства имен обычно являются элементами верхнего уровня в файлах F#.
Синтаксис
namespace [rec] [parent-namespaces.]identifier
Замечания
Если вы хотите поместить код в пространство имен, первое объявление в файле должно объявить пространство имен. Содержимое всего файла становится частью пространства имен, если в файле нет других объявлений пространств имен. Если это так, все коды до следующего объявления пространства имен считаются в пределах первого пространства имен.
Пространства имен не могут напрямую содержать значения и функции. Вместо этого значения и функции должны быть включены в модули, а модули включаются в пространства имен. Пространства имен могут содержать типы и модули.
Комментарии к XML-документам можно объявить над пространством имен, но они игнорируются. Директивы компилятора также можно объявить над пространством имен.
Пространства имен можно объявлять явно с помощью пространства имен ключевое слово или неявно при объявлении модуля. Чтобы явно объявить пространство имен, используйте пространство имен ключевое слово за именем пространства имен. В следующем примере показан файл кода, объявляющий пространство Widgets
имен с типом и модулем, включенным в это пространство имен.
namespace Widgets
type MyWidget1 =
member this.WidgetName = "Widget1"
module WidgetsModule =
let widgetName = "Widget2"
Если все содержимое файла в одном модуле, можно также объявить пространства имен неявно с помощью 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
Если в одном или нескольких пространствах имен требуется несколько модулей, необходимо использовать объявления локального модуля. При использовании объявлений локального модуля нельзя использовать полное пространство имен в объявлениях модуля. В следующем коде показан файл с объявлением пространства имен и двумя объявлениями локального модуля. В этом случае модули содержатся непосредственно в пространстве имен; Неявно создан модуль, имеющий то же имя, что и файл. Любой другой код в файле, например 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"
Пространства имен в файлах и сборках
Пространства имен могут охватывать несколько файлов в одном проекте или компиляции. Фрагмент пространства имен терминов описывает часть пространства имен, включенного в один файл. Пространства имен также могут охватывать несколько сборок. Например, 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 (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
Обратите внимание, что исключение DontSqueezeTheBananaException
и класс Banana
ссылаются друг на друга. Кроме того, модуль BananaHelpers
и класс Banana
также ссылаются друг на друга. Это не удастся выразить в F#, если вы удалили rec
ключевое слово из MutualReferences
пространства имен.
Эта функция также доступна для модулей верхнего уровня.