Функциональные типы
Функциональный тип — это тип, значениями которого являются методы. Функциональные типы позволяют хранить методы в переменных, передавать их в другие методы как аргументы и возвращать как результат.
Имя функционального типа содержит типы параметров и возвращаемого значения, разделенные символом лямбда-операции ->
.
Например, функциональный тип, значением которого является метод, принимающий два параметра типа Число
и возвращающий значение типа Строка
:
(Число, Число)->Строка
Значение функционального типа может быть записано двумя способами:
-
как лямбда-выражение, например:
(Строка1, Строка2) -> Строка1.Длина() < Строка2.Длина()
-
как ссылка на существующий метод, например
&СравнитьНаМеньше
Имя типа
Имя функционального типа содержит типы параметров и возвращаемого значения, разделенные символом лямбда-операции ->
. Например:
-
Значением типа является метод с одним параметром типа
Число
, возвращающий значение типаЧисло
:знч Результат: (Число)->Число = ...
-
Значением типа является метод с двумя параметрами типа
Число
, возвращающий значение типаБулево
:знч Результат: (Число, Число)->Булево = ...
-
Значением типа является метод с двумя параметрами типа
Число
, возвращающий значение составного типа (Строка
илиНеопределено
):знч Результат: (Число, Число)->Строка? = ...
-
Значением типа является метод с одним параметром составного типа (
Число
илиНеопределено
),возвращающий значение составного типа (Строка
илиЧисло
):знч Результат: (Число?)->Строка|Число = ...
-
Значением типа является метод без параметров, возвращающий значение типа
Строка
:знч Результат: ()->Строка = ...
-
Значением типа является метод с одним параметром типа
Строка
, не возвращающий ничего:знч Результат: (Строка)->ничто = ...
ничто
никуда нельзя присвоить и с ним никак нельзя взаимодействовать;- Значение типа (XXX)->YYY можно присвоить в переменную типа (XXX)->ничто.
-
Составной тип, значением которого является либо
Неопределено
, либо метод с одним параметром типаЧисло
, возвращающий значение типаСтрока
:знч Результат: ((Число)->Строка)? = ...
-
Составной тип, значением которого является либо
Булево
, метод с одним параметром типаЧисло
, возвращающий значение типаСтрока
:знч Результат: ((Число)->Строка)|Булево = ...
Если функциональный тип входит в составной тип, то имя такого функционального типа должно быть заключено в скобки, иначе все, что следует за лямбда-операцией ->
, будет считаться составным типом результата.
-
Если в качестве типа переменной указано
неизвестно
, то проверка типов компилятора отключается и такое значение можно вызывать с любым количеством параметров. Будет ошибка или нет станет ясно только во время работы приложения:пер МойМетод: неизвестно
МойМетод(Истина, 44) // Ошибки компиляции нет
В общем виде имя функционального типа выглядит следующим образом:
(тип-параметра-1, ..., тип-параметра-n)->тип-результата
Где:
- тип-параметра-1, ..., тип-параметра-N — типы параметров, если они есть;
->
— лямбда-операция;- тип-результата — тип возвращаемого значения.
Вызов значения функционального типа
Синтаксически выглядит как вызов обычного метода:
[выражение.]имя([аргументы])
Например:
МойМетод()
Фильтровать(7)
Товар.Категория.Добавить("Принтер")
При этом действует следующий приоритет разрешения имен:
- Если существует метод с указанным именем (любого приоритета), то считается, что это вызов метода;
- Иначе ищется свойство с указанным именем в порядке приоритетов и считается это вызовом функционального типа.
Иерархия типов и вариантность
Значен ия функциональных типов обеспечивают ковариантность по возвращаемым типам и контравариантность по типам параметров.
Ковариантность по возвращаемым типам
Метод, возвращающий значение производного типа можно присвоить в метод, возвращающий значение базового типа:
пер п1: (Строка)->Объект // Базовый
пер п2: (Строка)->Число // Производный от Объект
п1 = п2 // OK
Метод, возвращающий значение простого типа можно присвоить в метод, возвращающий значение составного типа, в который входит этот простой тип:
пер п1: (Строка)->Число|Строка // Составной
пер п2: (Строка)->Число // Входит в составной
п1 = п2 // OK