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