11 · Процедуры и функции
Процедуры и функции
По мере роста программы одни и те же последовательности инструкций начинают повторяться, а длинное тело становится трудно читать. Подпрограмма решает обе задачи: повторяемый фрагмент получает имя, параметры и собственные локальные имена. В этой главе собраны объявления SUB и FUNCTION, передача параметров, вызовы и оператор RETURN.
Зачем выделять подпрограмму
Повторяемую последовательность инструкций можно назвать и вызвать из нескольких мест. Параметры передают входные значения, локальные переменные хранят состояние текущего вызова, а функция возвращает вычисленный результат.
SUB объединяет действие без результата, FUNCTION вычисляет значение, а RETURN завершает текущий вызов. В следующем примере обе формы стоят рядом: процедура печатает строку с обрамлением, функция возвращает квадрат числа.
SUB Banner(text AS STRING)
PRINT "=="; text; "=="
END SUB
FUNCTION Square(value AS INTEGER) AS INTEGER
RETURN value * value
END FUNCTION
Banner("Axiom")
PRINT Square(5)Программа выводит:
==Axiom==
25Процедура вызывается отдельной инструкцией и ничего не возвращает, поэтому её результат негде сохранить. Функция, напротив, участвует в выражении PRINT: значение 25 появляется там, где стоит её вызов.
Выбор объявления
Используйте SUB для действия, например вывода, записи файла или изменения параметра BYREF. Используйте FUNCTION, если вызывающему коду нужно значение определённого типа. Объявления доступны на верхнем уровне и локально внутри другой подпрограммы.
Передача параметров
Имя обозначает подпрограмму. Список параметров содержит объявления через запятую. Каждый параметр задаёт имя и тип после AS; пустой список допустим. Список аргументов содержит выражения в том же порядке. Тип аргумента должен совпадать с типом параметра либо допускать предусмотренное языком преобразование.
BYVAL применяется по умолчанию и передаёт независимую копию значения. Это правило действует для чисел, строк, массивов, TYPE, DICTIONARY и HASHSET. Вложенные изменяемые данные также копируются: изменение элемента массива или коллекции внутри параметра не меняет данные вызывающего кода. Аргумент фиксируется сразу после своего вычисления, до вычисления следующих аргументов. BYREF, напротив, явно связывает параметр с исходной переменной; изменение через такой параметр видно вызывающему коду. Функциональные значения с захватами и внешние ресурсы этим правилом автоматически не дублируются.
BYREF связывает параметр с переменной; массивная переменная передаётся с обязательным суффиксом []. Тип должен точно совпадать; преобразование аргумента не допускается. Поле записи, элемент массива и вычисляемое выражение не являются допустимым аргументом BYREF. Передача CONST через BYREF отвергается диагностикой MB2010; для изменяемого аргумента используйте обычную переменную DIM.
Массив в параметре и результате
Именованный массивный параметр записывается как values[] AS STRING; пустой суффикс после имени задаёт одно измерение, [,] — два. При вызове ShowBasket(fruits[]) передаётся весь массив, а не элемент. Безымянный тип результата записывается как AS STRING[] или AS INTEGER[,]. Полные формы и примеры приведены в статьях о параметрах SUB и о массивном результате FUNCTION.
Функции как значения
Функция без параметров BYREF может сохраняться в функциональной переменной, передаваться аргументом и возвращаться из другой функции. Вложенные функции могут захватывать внешние локальные значения. Такие функции применяются, например, в ARRAYMAP и ARRAYFILTER.
Темы раздела
SUB · FUNCTION · Вызовы · RETURN · Методы TYPE · Пользовательская обработка массивов