Какой статус имеет инкремент в Go и что это запрещает в выражениях?
В Go инкремент и декремент являются операторами-утверждениями, а не выражениями, возвращающими значение. Поэтому x++ допустим только как отдельная инструкция: его нельзя использовать в присваивании, аргументе функции, условии или другом выражении.
Go сознательно разделяет операции, изменяющие состояние, и выражения, вычисляющие значение. Это делает синтаксис языка более однозначным: изменение переменной не маскируется внутри более крупного выражения.
В отличие от языков, где постфиксный инкремент возвращает старое значение, а префиксный — новое, Go не предоставляет инкременту возвращаемого результата. В языке существует только постфиксная форма x++; формы ++x нет.
Если ожидать от инкремента поведения C-подобных языков, можно попытаться передать его результат в функцию или использовать в присваивании. Такой код не компилируется, поскольку компилятор не рассматривает x++ как значение.
Это ограничение предотвращает неочевидные зависимости от порядка вычисления и случайное смешивание чтения переменной с её изменением. Если требуется получить значение после увеличения, операцию нужно разделить на два шага.
Инкремент допустим только в качестве самостоятельного оператора над адресуемой переменной. Он увеличивает значение на единицу, но не образует выражение, которое можно вложить в другую операцию.
После x++ переменная x равна пяти, а затем это значение можно прочитать обычным выражением y := x. Записи, эквивалентные передаче результата x++ в функцию или присваиванию его другой переменной, недопустимы.
Оператор работает только с переменной подходящего числового типа, значение которой можно изменить. Нельзя инкрементировать константу или произвольный результат вычисления, поскольку такие значения не являются изменяемыми переменными.
Практический компромисс состоит в том, что иногда требуется дополнительная строка кода. Взамен граница между вычислением значения и побочным эффектом остаётся явной, а порядок действий проще анализировать.
В обработчике нужно вернуть текущий номер записи и затем увеличить счётчик для следующей записи. Попытка получить старое значение через инкремент как часть выражения невозможна.
Вариант с отдельным сохранением старого значения работает явно, но требует двух переменныхых операций: сначала копирования, затем увеличения. Вариант с увеличением до чтения вернёт уже следующий номер и изменит требуемую семантику.
Выбранное решение — сначала сохранить текущее значение, затем выполнить отдельный инкремент. Такой код компилируется, однозначно показывает порядок побочных эффектов и не зависит от семантики инкремента в других языках.
++x?Нет. В Go определена только постфиксная форма x++; префиксный инкремент синтаксически недопустим. Это не вопрос различия возвращаемого значения: у Go-инкремента результата вообще нет.
Нет. Условие и аргумент требуют выражения, вычисляющего значение, а x++ является отдельной инструкцией. Нужно предварительно изменить переменную отдельной строкой, а затем использовать её обычное значение.
Да, если такой элемент или поле адресуемы и имеют изменяемый числовой тип. Например, элемент среза можно увеличить отдельной инструкцией, но нельзя встроить саму операцию инкремента в другое выражение.