Пространства имен

Последнее обновление: 15.12.2023

Пространства имен позволяют сгруппировать код в отдельные логические области.

Для организации пространства имен применяется ключевое слово namespace, после которого идет название название пространства имен:

namespace название_пространства_имен

При помещении кода в пространство имен определение пространства имен должно быть первым выражением в файле. В этом случае весь остальной код файла будет входить в данное пронстранство имен. При этом пространства имен напрямую не могут содержать значения и функции или вызовы функций. Они могут содержать только типы и модули. Поэтому если надо определить какие-то значения или функции, то внутри пространства имен для этого определяется локальный модуль.

Например, пусть у нас в проекте есть файл Hello.fs:

Пространства имен namespace в F#

Определим в нем пространство имен с названием 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()
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850