Пространства имен позволяют сгруппировать код в отдельные логические области.
Для организации пространства имен применяется ключевое слово namespace, после которого идет название название пространства имен:
namespace название_пространства_имен
При помещении кода в пространство имен определение пространства имен должно быть первым выражением в файле. В этом случае весь остальной код файла будет входить в данное пронстранство имен. При этом пространства имен напрямую не могут содержать значения и функции или вызовы функций. Они могут содержать только типы и модули. Поэтому если надо определить какие-то значения или функции, то внутри пространства имен для этого определяется локальный модуль.
Например, пусть у нас в проекте есть файл Hello.fs:
Определим в нем пространство имен с названием HelloMessages
:
namespace HelloMessages type MessageFunc = unit -> unit module Messages = let hello = "Hello" let goodMorning = "Good Morning" let goodEvening = "Good Evening" let printHello() = printfn "%s" hello
В этом пространстве имен определен тип MessageFunc
, который представляет тип функции, которая принимает параметр типа unit
и возвращает
значение типа unit
.
Также в пространстве имен определен модуль, который содержит три значения и одну функцию.
Для обращения к типам и модулям пространства имен перед ними через точку указывается название содержащего их пространства имен:
пространство_имен.тип пространство_имен.модуль
Теперь используем выше определенное пространство имен HelloMessages в главном Файле проекта Program.fs:
let sayGoodMorning: HelloMessages.MessageFunc = fun()->printfn $"{HelloMessages.Messages.goodMorning}" sayGoodMorning() HelloMessages.Messages.printHello()
Здесь определяется значение sayGoodMorning
, которое имеет тип HelloMessages.MessageFunc
и представляет функцию, которая
обращается к значению HelloMessages.Messages.goodMorning
. Затем вызываем эту функцию. И также здесь вызывается функция HelloMessages.Messages.printHello
.
Но прописывать перед названиями модулей и типов названия пространств имен увеличивает объем кода, и мы можем, как и в случае с модулями, подключить все пространство имен с помощью оператора open:
open HelloMessages // подключаем пространство имен HelloMessages open Messages // подключаем модуль Messages из пространства имен HelloMessages let sayGoodMorning: MessageFunc = fun()->printfn $"{goodMorning}" sayGoodMorning() printHello()
В одном файле может быть определено больше одного пространства имен. В этом случае все типы и модули, которые идут до определения пространства имен, принадлежат предыдущему пространству имен:
namespace HelloMessages type MessageFunc = unit -> unit namespace EngMessages module Messages = let hello = "Hello" let goodMorning = "Good Morning" let goodEvening = "Good Evening" let printHello() = printfn "%s" hello
Здесь определены два пространства имен. Пространству имен HelloMessages
принадлежит тип MessageFunc
, тогда как модуль Messages принадлежит
пространству имен EngMessages
.
Обращения к этим пространствам имен:
open HelloMessages // подключаем пространство имен HelloMessages open EngMessages.Messages // подключаем модуль Messages из пространства имен EngMessages let sayGoodMorning: MessageFunc = fun()-> printfn "%s" goodMorning sayGoodMorning() printHello()
Пространства имен могут быть вложенными. В этом случае при определении вложенного пространства имен перед его названием указывается имя родительского пространства имен:
namespace HelloMessages type MessageFunc = unit -> unit namespace HelloMessages.EngMessages module Messages = let hello = "Hello" let goodMorning = "Good Morning" let goodEvening = "Good Evening" let printHello() = printfn "%s" hello
Здесь пространство EngMessages
является вложенным по отношению к HelloMessages. И чтобы обратиться, например, к функции printHello
из EngMessages,
нам надо указать все пространства имен:
HelloMessages.EngMessages.Messages.printHello()
При опредлении модуля уровня файла неявно также определяется одноименное пространство имен:
module Hello type MessageFunc = unit -> unit module Messages = let hello = "Hello" let goodMorning = "Good Morning" let goodEvening = "Good Evening" let printHello() = printfn "%s" hello
В данном случае автоматически неявно будут определено пространство имен Hello для всей функциональности модуля Hello.
Но также при определении модуля можно явно указать пространство имен, к которому принадлежит модуль уровня файла:
module HelloMessages.Hello type MessageFunc = unit -> unit module Messages = let hello = "Hello" let goodMorning = "Good Morning" let goodEvening = "Good Evening" let printHello() = printfn "%s" hello
Название пространства имен указывается перед именем модуля через точку. То есть в данном случае модуль Hello принадлежит пространству имен HelloMessages.
Использование такого модуля в Program.fs:
open HelloMessages.Hello // подключаем модуль Hello из пространства имен HelloMessages open Messages // подключаем модуль Messages из модуля HelloMessages.Hello let sayGoodMorning: MessageFunc = fun() -> printfn "%s" goodMorning sayGoodMorning() printHello()