Skip to content

Общие операторы: о переполнениях

Переполнения не допускаются для типизированных постоянных значений, но допускаются для неконстантных и нетипизированных постоянных значений, будь то промежуточные или окончательные результаты. Переполнения будут усечены (или завернуты) для непостоянных значений, но переполнения (для типов по умолчанию) для нетипизированного постоянного значения не будут усечены (или завернуты). 

Пример:

О результатах операций арифметических операторов

За исключением операций побитового сдвига, результат операции бинарного арифметического оператора:

  • Является типизированным значением одного и того же типа двух операндов, если оба операнда являются типизированными значениями одного и того же типа.
  • Является типизированным значением того же типа, что и типизированный операнд, если только один из двух операндов является типизированным значением. При вычислении другое (нетипизированное) значение будет выведено как значение типа типизированного операнда. Нетипизированный операнд будет неявно преобразован в тип типизированного операнда.
  • Остается нетипизированным значением, если оба операнда не типизированы. Тип значения результата по умолчанию — один из двух типов по умолчанию, и он появляется последним в этом списке: int, rune, float64, complex128. Например, если тип по умолчанию одного нетипизированного операнда — int, а другого — rune, то тип по умолчанию нетипизированного значения результата — rune.

Правила для результата операции оператора побитового сдвига могут казаться сложными. Во-первых, значение результата всегда является целым числом. Является ли он типизированным или нетипизированным, зависит от конкретных сценариев.

  • Если левый операнд является типизированным значением (целочисленным значением), то тип результата совпадает с типом левого операнда.
  • Если левый операнд является нетипизированным значением, а правый операнд является константой, то левый операнд всегда будет обрабатываться как целочисленное значение, если его тип по умолчанию не является целочисленным типом, он должен быть представлен как нетипизированное целое число и его тип умолчанию будет рассматриваться как int. В таких случаях результат также является нетипизированным значением, а тип результата по умолчанию совпадает с типом левого операнда.
  • Если левый операнд является нетипизированным значением, а правый операнд — непостоянным целым числом, то левый операнд будет сначала преобразован к типу, который он принял бы, если бы операция побитового сдвига была заменена только его левым операндом. Результатом является типизированное значение, тип которого является предполагаемым типом.

Пример:

Другой пример (операции побитового сдвига):

Последнее правило для работы оператора побитового сдвига состоит в том, чтобы избежать случаев, когда некоторые операции побитового сдвига возвращают разные результаты на разных архитектурах, но различия не будут обнаружены во времени. Например, если операнд 1 выводится как int вместо int64, побитовая операция в строке 13 (или строке 12) вернет разные результаты для 32-битных архитектур (0) и 64-битных архитектур (0x100000000), что может привести к некоторым трудно обнаруживаемым ошибкам. 

Одно интересное следствие последнего правила для операции побитового сдвига показано в следующем фрагменте кода.

Причина того, что последние две строки не могут быть скомпилированы, заключается в том, что они обе эквивалентны следующим двум строкам.

Другой пример:

Вышеприведенная программа печатает 2 0, потому что последние две строки эквивалентны.