proc: объявление процедуры
Разбираемся, как в Nim оформить кусок кода в процедуру: с параметрами, типами и возвращаемым значением.
Процедура (procedure) — именованный блок кода, который можно вызывать много раз с разными входными данными. В Nim процедуры объявляют через ключевое слово
proc.
Зачем это нужно
Представь, что ты пишешь программу, которая несколько раз считает площадь прямоугольника: в одном месте — для комнаты, в другом — для участка земли, в третьем — для баннера. Если каждый раз писать ширина * высота заново, велика вероятность где-нибудь ошибиться или забыть учесть новое условие (например, что стороны не могут быть отрицательными). Гораздо надёжнее написать код один раз, дать ему имя и потом просто вызывать это имя с нужными числами.
Именно для этого в любом языке программирования есть процедуры и функции. В Nim их называют procedures и объявляют ключевым словом proc. Отдельного слова «function» для чистых функций (которые не имеют побочных эффектов) в базовом синтаксисе нет — Nim различает это через ключевое слово func, но об этом позже. Пока используем proc — это рабочая лошадка, с которой начинают все.
Синтаксис proc
Вот процедура, которая складывает два целых числа:
proc sum(a: int, b: int): int =
result = a + b
echo sum(3, 4)Вывод:
7Разберём эту запись по кусочкам, потому что в Nim каждая часть здесь значима и ничего лишнего нет.
Построчный разбор
proc— ключевое слово, с которого начинается объявление любой процедуры.sum— имя процедуры. По нему её потом вызывают.(a: int, b: int)— список параметров в круглых скобках. Каждый параметр записывается какимя: тип. В Nim типы параметров указывать обязательно — компилятор не станет угадывать, что именно ты хочешь туда передать.: intпосле закрывающей скобки — тип возвращаемого значения. Он тоже обязателен, если процедура что-то возвращает.=— открывает тело процедуры. В Nim отступы (пробелы) значимы, как в Python: всё, что написано с отступом ниже строки сproc, — это тело процедуры.result = a + b— здесь происходит магия:result— это специальная переменная, которую Nim создаёт автоматически внутри каждой процедуры с возвращаемым типом. Присвоить ей значение — то же самое, что сказать «вот что нужно вернуть».
Заметь: в этом примере нет отдельного слова return. Оно в Nim тоже есть и работает (можно написать return a + b), но чаще используют именно переменную result — она изначально уже создана с «нулевым» значением подходящего типа (для int это 0), и в конце процедуры её значение возвращается автоматически.
Вариант с явным return
Если тебе привычнее явный возврат, как в большинстве других языков, вот та же процедура иначе:
proc multiply(a: int, b: int): int =
return a * b
echo multiply(5, 6)Вывод:
30Оба варианта — с result и с return — рабочие и дают одинаковый результат. return удобен, когда нужно выйти из процедуры досрочно (например, внутри условия), а result — когда значение собирается постепенно, шаг за шагом.
Процедура без возвращаемого значения
Не всякая процедура обязана что-то возвращать. Если она просто выполняет действие — например, печатает текст, — тип результата в объявлении не указывают вовсе:
proc greet(name: string) =
echo "Привет, " & name & "!"
greet("Аня")Вывод:
Привет, Аня!Здесь после списка параметров нет двоеточия с типом — сразу идёт = и тело. Такая процедура выполняет побочное действие (вывод на экран) и ничего не возвращает вызывающему коду.
Мини-пример: процедура с несколькими шагами
Процедуры не обязаны быть однострочными. Внутри может быть сколько угодно логики — важно лишь, чтобы в конце (через result или return) было понятно, что процедура отдаёт наружу:
proc isEven(n: int): bool =
if n mod 2 == 0:
result = true
else:
result = false
echo isEven(10)
echo isEven(7)Вывод:
true
falseПроцедура isEven принимает целое число и возвращает bool — логическое значение true или false. Внутри мы используем mod — это оператор остатка от деления (в других языках его часто пишут как %). Если остаток от деления на 2 равен нулю, число чётное.
Частые ошибки
- Забыли указать тип параметра. Запись вида
proc sum(a, b): intбез типов не скомпилируется — Nim статически типизированный язык, и каждый параметр должен знать свой тип. Правильно:proc sum(a: int, b: int): intили короче —proc sum(a, b: int): int, если оба параметра одного типа (тип указывается один раз после запятой). - Забыли тип возвращаемого значения при его наличии. Если процедура использует
resultилиreturn, но в объявлении нет: типпосле скобок — компилятор пожалуется, чтоresultне определён. - Перепутали отступы. Так же, как в Python, тело процедуры определяется отступом. Если строка тела написана без отступа или с отступом, отличным от остальных строк тела, компилятор выдаст ошибку синтаксиса.
- Ожидают, что
resultнужно объявлять вручную. Не нужно писатьvar result: int— Nim создаёт эту переменную сам на основе типа, указанного после скобок.
Итоги
- Процедура в Nim объявляется словом
proc, дальше — имя, параметры с обязательными типами в скобках и (если нужно) тип возвращаемого значения после двоеточия. - Тело процедуры отделяется знаком
=и записывается с отступом, как блоки в Python. - Вернуть значение можно двумя способами: присвоить его переменной
result(она создаётся автоматически) или использовать явныйreturn. - Если процедура ничего не возвращает, тип результата в объявлении просто не указывают.