TGViewer
Из Solidity в AI и дальше Из Solidity в AI и дальше @solidityset · 2.49K subscribers
Post #1500 594
Погружение в Core Solidity. Часть 4

Функции высшего порядка и анонимные функции

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

В качестве примера рассмотрим следующий фрагмент, реализующий пользовательскую декодировку ABI для тройки логических значений из одного слова:

forall T . function unpack_bools(fn : (bool, bool, bool) -> T) -> ((word) -> T) {
return lam (bools : word) -> {
let wordToBool = lam (w : word) { return w > 0; };

// extract the right-most bit from `bools`
let b0 = wordToBool(and(bools, 0x1));

// shift `bools` by one and extract the right-most bit
let b1 = wordToBool(and(shr(1, bools), 0x1));

// shift `bools` by two and extract the right-most bit
let b2 = wordToBool(and(shr(2, bools), 0x1));

return fn(b0, b1, b2);
};
}


Функция unpack_bools реализует пользовательскую декодировку ABI. Она является функцией высшего порядка, которая «оборачивает» входную функцию, принимающую три отдельных логических значения и возвращающую значение произвольного типа T, извлекая аргументы из трёх младших битов входного слова. Такой пример невозможно реализовать в классическом Solidity, даже с использованием модификаторов, поскольку они не могут изменять аргументы, передаваемые внутрь оборачиваемой функции.

Кроме того, поддерживается определение (некурсивных) анонимных функций с помощью ключевого слова lam. Функции, определённые таким образом, могут захватывать значения из области видимости, в которой они объявлены. В качестве примера рассмотрим вспомогательную функцию для тестирования, подсчитывающую количество вызовов произвольной функции:

forall T U . function count_calls(fn : (T) -> U) -> (memory(word), (T) -> U) {
let counter : memory(word) = allocate(32);
return (counter, lam (a : T) -> {
counter += 1;
return fn(a);
});
}


Реализация здесь аналогична тому, как это сделано в системных языках, таких как Rust и C++: компилятор генерирует уникальный тип для каждой анонимной функции, содержащей захваченные значения, а эти уникальные типы становятся вызываемыми за счёт принадлежности к специальному типовому классу «вызываемых» (invokable), подобно трейту Fn в Rust. Такой подход обеспечивает высокую эффективность с точки зрения затрат газа во время выполнения.

Вывод типов

Core Solidity поддерживает вывод типов почти в любом контексте. Аннотации типов обычно требуются только тогда, когда это желательно для улучшения читаемости или понимания кода. Алгоритм вывода типов разрешим, а ситуации, в которых возникает неоднозначность и требуется явная аннотация, крайне ограничены. Благодаря этому удаётся избавиться от большого количества синтаксического шума, присущего классическому Solidity.

Например, присваивание выражения переменной в классическом Solidity нередко приводит к избыточным аннотациям, даже если типы уже присутствуют в самом выражении:

(bytes memory a, bytes memory b) = abi.decode(input, (bytes, bytes));


То же самое определение в Core Solidity выглядит значительно чище:

let (a, b) = abi.decode(input, (uint256, uint256));


Ещё одна частая причина раздражения при работе с классическим Solidity — синтаксический шум при определении литералов массивов. Рассмотрим следующий фрагмент:

uint256[3] memory a = [1, 2, 3];


Это объявление отвергается компилятором классического Solidity со следующей ошибкой:

Error: Type uint8[3] memory is not implicitly convertible to expected type uint256[3] memory.


Причина ошибки заключается в том, что классический Solidity реализует ограниченную и специализированную форму вывода типов для литералов массивов: тип элементов массива определяется как тип первого выражения в списке, к которому можно неявно привести все остальные элементы (в данном случае — uint8). Затем компилятор выдаёт ошибку несоответствия типов при попытке присвоить это значение переменной несовместимого типа.
  • ❤ 4
More from @solidityset
  1. Sep 22, 2026Какой язык программирования учить сейчас? На днях в Твиттере увидел небольшой пост о разви…
  2. Sep 18, 2026Интересная модель Jev Буквально пару дней назад в Твиттере многие начали обсуждение новой…
  3. Sep 14, 2026Графы повсюду Если вы также следите за новостями в мире ИИ, то наверняка уже все чаще встр…
  4. Sep 10, 2026GTA6, Cyberleek, блокчейн и безопасность Увидел несколько постов (тут и тут) про Cyberleek…
  5. Sep 9, 2026Работа с чистой энергией Дисклеймер Сегодня ава и название канала, наконец, поменялись. Я…
  6. Sep 9, 2026Channel name was changed to «Из Solidity в AI и дальше»
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →