Функции
Эта страница переведена сообществом на русский язык, но н уждается в улучшениях. Если вы хотите принять участие в переводе свяжитесь с @alexgton.
Программа FunC по сути является списком объявлений/определений функций и объявлений глобальных переменных. В этом разделе рассматривается первая тема.
Любое объявление или определение функции начинается с общего шаблона, а затем следует одно из трех:
-
одиночный
;, что означает, что функция объявлена, но еще не определена. Она может быть определена позже в том же файле или в каком-либо другом файле, который передается компилятору FunC перед текущим. Например,int add(int x, int y);это простое объявление функции с именем
addтипа(int, int) -> int. -
определение тела функции ассемблера. Это способ определения функций с помощью примитивов TVM низкого уровня для последующего использования в программе FunC. Например,
int add(int x, int y) asm "ADD";это ассемблерное определение той же функции
addтипа(int, int) -> int, которое будет транслироваться в код операции TVMADD. -
обычное определение тела функции блочного оператора. Это обычный способ определения функций. Например,
int add(int x, int y) {
return x + y;
}это обычное определение функции
add.
Объявление функции
Как уже было сказано, любое объявление или определение функции начинается с общего шаблона. Ниже приведен:
[<forall declarator>] <return_type> <function_name>(<comma_separated_function_args>) <specifiers>
где [ ... ] соответствует необязательной записи.
Имя функции
Имя функции может быть любым идентификатором, а также может начинаться с символов . или ~. Значение этих символов объясняется в разделе операторов.
Например, udict_add_builder?, dict_set и ~dict_set являются допустимыми и разными именами функций. (Они определены в stdlib.fc.)
Специальные имена ф ункций
FunC (фактически ассемблер Fift) имеет несколько зарезервированных имен функций с предопределенными идентификаторами.
mainиrecv_internalимеют id = 0recv_externalимеет id = -1run_ticktockимеет id = -2
Каждая программа должна иметь функцию с id 0, то есть функцию main или recv_internal.
run_ticktock вызывается в транзакциях ticktock специальных смарт-контрактов.
Внутренние получения
recv_internal вызывается, когда смарт-контракт получает входящее внутреннее сообщение.
При запуске TVM в стеке есть несколько переменных, задавая аргументы в recv_internal, мы даем коду смарт-контракта информацию о некоторых из них. Те аргументы, о которых код не будет знать, просто будут лежать внизу стека и никогда не будут затронуты.
Итак, каждое из следующих объявлений recv_internal является правильным, но те, у которых меньше переменных, будут тратить немного меньше газа (каждый неиспользованный аргумент добавляет дополнительные инструкции DROP)
() recv_internal(int balance, int msg_value, cell in_msg_cell, slice in_msg) {}
() recv_internal(int msg_value, cell in_msg_cell, slice in_msg) {}
() recv_internal(cell in_msg_cell, slice in_msg) {}
() recv_internal(slice in_msg) {}