0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>Теги: операторы, функции, go, defer</p>
1
<p>Теги: операторы, функции, go, defer</p>
2
<p><strong>Оператор defer</strong>служит для планирования вызова функции, то есть речь идет, по сути, об отложенной функции. Это довольно необычный, но эффективный способ справиться с ситуациями, когда ресурсы важно освободить вне зависимости от того, какой именно путь принимает функция для возврата. Традиционный пример -- разблокировка мьютекса либо закрытие файла.</p>
2
<p><strong>Оператор defer</strong>служит для планирования вызова функции, то есть речь идет, по сути, об отложенной функции. Это довольно необычный, но эффективный способ справиться с ситуациями, когда ресурсы важно освободить вне зависимости от того, какой именно путь принимает функция для возврата. Традиционный пример -- разблокировка мьютекса либо закрытие файла.</p>
3
<p>Давайте посмотрим, как это работает:</p>
3
<p>Давайте посмотрим, как это работает:</p>
4
<p>Отсрочка вызова функции, той же Close, имеет следующие плюсы:</p>
4
<p>Отсрочка вызова функции, той же Close, имеет следующие плюсы:</p>
5
<ol><li>Гарантируется, что вы не забудете закрыть файл (такую ошибку легко допустить, если вы позже выполните редактирование функции для добавления нового пути возврата).</li>
5
<ol><li>Гарантируется, что вы не забудете закрыть файл (такую ошибку легко допустить, если вы позже выполните редактирование функции для добавления нового пути возврата).</li>
6
<li>Отсрочка вызова означает, что закрытие будет находиться рядом с открытием, а это гораздо понятнее, чем помещение в конец функции.</li>
6
<li>Отсрочка вызова означает, что закрытие будет находиться рядом с открытием, а это гораздо понятнее, чем помещение в конец функции.</li>
7
</ol><p>Аргументы для отложенной функции (включают получателя, когда функция является методом) оцениваются, если выполняется<strong>defer</strong>, а не в том случае, когда выполняется вызов (<strong>call</strong>). Такое положение вещей поможет избежать лишних забот о переменных, которые меняют значения в случае выполнения функции, что тоже значит, что отложить исполнение нескольких функций может лишь одно место отложенного вызова. Рассмотрим простой пример:</p>
7
</ol><p>Аргументы для отложенной функции (включают получателя, когда функция является методом) оцениваются, если выполняется<strong>defer</strong>, а не в том случае, когда выполняется вызов (<strong>call</strong>). Такое положение вещей поможет избежать лишних забот о переменных, которые меняют значения в случае выполнения функции, что тоже значит, что отложить исполнение нескольких функций может лишь одно место отложенного вызова. Рассмотрим простой пример:</p>
8
<p>Важно отметить, что отложенные функции выполняются в соответствии с<strong>LIFO</strong>(last-in-first-out), следовательно, данный код вызовет "4 3 2 1 0" для печати после возврата из функции. Также можно написать пару простых трассировок:</p>
8
<p>Важно отметить, что отложенные функции выполняются в соответствии с<strong>LIFO</strong>(last-in-first-out), следовательно, данный код вызовет "4 3 2 1 0" для печати после возврата из функции. Также можно написать пару простых трассировок:</p>
9
<p>Еще момент: аргументы отложенных функций оцениваются во время выполнения<strong>defer</strong>. Например, процедура трассировки способна установить аргумент для процедуры отслеживания. Смотрим пример ниже:</p>
9
<p>Еще момент: аргументы отложенных функций оцениваются во время выполнения<strong>defer</strong>. Например, процедура трассировки способна установить аргумент для процедуры отслеживания. Смотрим пример ниже:</p>
10
<p>Будет напечатано следующее:</p>
10
<p>Будет напечатано следующее:</p>
11
<p>Для разработчиков, которые привыкли управлять ресурсами на уровне блоков на других языках программирования, оператор<strong>defer</strong>может показаться странным, однако его преимущество заключается в том, что он не на основе блоков, а на основе функций.</p>
11
<p>Для разработчиков, которые привыкли управлять ресурсами на уровне блоков на других языках программирования, оператор<strong>defer</strong>может показаться странным, однако его преимущество заключается в том, что он не на основе блоков, а на основе функций.</p>
12
<p><em>По материалам https://golang-blog.blogspot.com/.</em></p>
12
<p><em>По материалам https://golang-blog.blogspot.com/.</em></p>
13
13