Перейти к основному содержимому

Функциональные типы

Функциональный тип — это тип, значениями которого являются методы. Функциональные типы позволяют хранить методы в переменных, передавать их в другие методы как аргументы и возвращать как результат.

Имя функционального типа содержит типы параметров и возвращаемого значения, разделенные символом лямбда-операции ->.

Например, функциональный тип, значением которого является метод, принимающий два параметра типа Число и возвращающий значение типа Строка:

(Число, Число)->Строка

Значение функционального типа может быть записано двумя способами:

Имя типа

Имя функционального типа содержит типы параметров и возвращаемого значения, разделенные символом лямбда-операции ->. Например:

  • Значением типа является метод с одним параметром типа Число, возвращающий значение типа Число:

    знч Результат: (Число)->Число = ...
  • Значением типа является метод с двумя параметрами типа Число, возвращающий значение типа Булево:

    знч Результат: (Число, Число)->Булево = ...
  • Значением типа является метод с двумя параметрами типа Число, возвращающий значение составного типа (Строка или Неопределено):

    знч Результат: (Число, Число)->Строка? = ...
  • Значением типа является метод с одним параметром составного типа (Число или Неопределено),возвращающий значение составного типа (Строка или Число):

    знч Результат: (Число?)->Строка|Число = ...
  • Значением типа является метод без параметров, возвращающий значение типа Строка:

    знч Результат: ()->Строка = ...
  • Значением типа является метод с одним параметром типа Строка, не возвращающий ничего:

    знч Результат: (Строка)->ничто = ...
примечание
  • ничто никуда нельзя присвоить и с ним никак нельзя взаимодействовать;
  • Значение типа (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

Присваивания в другую сторону неверны.

Примеры

См. также