Модификаторы доступа

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

Модификаторы доступа позволяют ограничить доступ к функциональности программы определенным контекстом. Модификаторы доступа применяются к модулям, определениям значений, функциям, типам, методам, свойствам и явно определенным полям (методы, свойства и явно определяемые поля будут рассмотрены в последующих статьях).

В F# есть следующие модификаторы доступа:

  • public: функционал доступен из любого места программы, в том числе вне проекта в других проектах

  • internal: функционал доступен только из текущего проекта

  • private: функционал доступен из типа или модуля, в котором данный функционал определен

Модификаторы указываются перед названием модулей, функций, типов, значений, но после ключевых слов module, let, type. Если модификатор доступа явным образом не указан, то уровень доступности аналогичен модификатору public.

Чтобы подробнее разобраться в модификаторах доступа, определим два проекта F# - проект консольного приложения "HelloApp" и проект библиотеки классов "Messages", который будет содержать файл кода Library.fs с некоторым автосгенерированным кодом:

Проект библиотеки классов Class Library в F#

При этом проект библиотеки классов "Messages" подключен в проект консольного приложения "HelloApp".

Откроем файл Library.fs в проекте Messages и изменим его код следующим образом:

namespace Messages

type public MessageFuncType = unit -> unit

module internal Texts = 
    let public hello = "Hello"                  // доступно везде в проекте
    let internal goodMorning = "Good Morning"   // доступно только в пределах проекта Messages
    let private goodEvening = "Good Evening"    // доступно только в пределах модуля Text

module public Funcs = 
    let public sayHello() = printfn $"{Texts.hello}"            // доступно везде
    let internal sayMorning() = printfn $"{Texts.goodMorning}"  // доступно только в пределах проекта Messages
    //let public sayEvening() = printfn $"{Texts.goodEvening}"  // так нельзя - не доступа к Texts.hello

Итак, в пространстве имен Messages определено три сущности:

  • Тип MessageFuncType - он имеет модификатор доступа public, поэтому доступен из любого места программы

  • Модуль Texts определяет текст сообщений - он имеет модификатор доступа internal, поэтому доступен из любого места текущего проекта Messages

  • Модуль Funcs определяет функции для вывода текста сообщений - он имеет модификатор доступа public, поэтому доступен из любого места программы

Теперь рассмотрим модуль Funcs.

Первая функция - sayHello() обращается к значению hello из модуля Texts

let public sayHello() = printfn $"{Texts.hello}" 

Здесь проблем никаких нет - это поле определено с модификатором public, поэтому достуно вне модуля Texts в любых других модулях текущего проекта.

Вторая функция sayMorning() обращается к значению goodMorning из модуля Texts

let internal sayMorning() = printfn $"{Texts.goodMorning}"

Здесь то же проблем никаких нет - это поле определено с модификатором internal, поэтому достуно вне модуля Texts в любых других модулях текущего проекта.

Теперь возьмем закомментрированную функцию - sayEvening

let public sayEvening() = printfn $"{Texts.goodEvening}" 

Эта функция обращается к значению goodEvening из модуля Texts, которое имеет модификатор private, поэтому доступно только внутри модуля Texts

Теперь изменим код файла Program.fs в главном проекте следующим образом:

open Messages
// open Texts   // модуль Texts недоступен
open Funcs      // модуль Funcs доступен

let printMessage : MessageFuncType = fun()->printfn "Hi F#" // тип MessageFuncType доступен

sayHello()          // функция sayHello доступна
// sayMorning()    // функция sayMorning не доступна

Здесь мы видим, что модуль Texts из пространства имен Messages не доступен, поскольку он определен с модификатором internal и поэтому доступен только внутри своего проекта.

А вот модуль Funcs определен с модификатором public, поэтому доступен из других проектов. Однако среди функциональности в других проектах будет доступна только та функциональность, которая определена с модификатором . Так, мы можем в других проектах использовать его функцию sayHello с модификатором public, но не можем использовать функцию sayMorning с модификатором internal.

И также поскольку тип MessageFuncType имеет модификатор public, то он также доступен из других проектов.

Модификаторы внешних сущностей

Если мы вернемся к проекту Messages и его модулю Texts, то можем увидеть, что вложенная сущность - значение hello имеет модификатор public:

module internal Texts = 
    let public hello = "Hello" 

Но в этом модификаторе нет смысла, поскольку внешняя сущность - модуль Texts имеет модификатор internal, что ограничивает его использование текущим проектом. Соответственно, значение hello также можно использовать только в рамках текущего проекта, несмотря на модификатор public.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850