Авторы языка посчитали, что с правилами приведения типов для чисел в языке Си имеются большие проблемы. Им показалось, что одной из существенных проблем в Си являются ошибки, связанные с неправильным использованием арифметических операторов для чисел разных типов. В результате они придумали нечто:
https://blog.golang.org/constants Суть в том, что для констант действуют одни правила, а для переменных другие.
Это приводит к следующим эффектам:
var a = -1;
fmt.Println(uint32(a)); // OK
const b = -1;
fmt.Println(uint32(b)); constant -1 overflows uint32
Почему для переменных переполнения разрешено, а для констант нет? (Потому что в одном случае в момент компиляции можно проверить, а в другом нет. Серьезно?)
Или таким:
var a = 9223372036854775296 + 1.0;
const b = 9223372036854775296 + 1.0;
fmt.Println(uint64(a), " ", uint64(b)); // 9223372036854775808 9223372036854775297
Сравним с C++:
auto a = 9223372036854775296 + 1.0;
constexpr auto b = 9223372036854775296 + 1.0;
std::cout << uint64_t(a) << " " << uint64_t(b); // 9223372036854775808 9223372036854775808
Мне такой подход кажется нелогичным из-за отсутствия единообразия в правилах вычисления переменных и констант. В подходе С++ нужно понять как работает приведение типов и арифметика. Константность выражения на способ вычисления не влияет. В Go, как и в любом другом языке с конечнозначными числами, от необходимости понимания арифметики уйти не получится, но в отличие от С++, придется помнить разные правила для констант и переменных.
Выглядит так, что хотели обезопасить программистов от "сложных" правил арифметики чисел, а в итоге только всё усложнили и сделали менее удобным. Это не та область программирования, в которой нужно что-то пытаться упростить. Кажущаяся сложность арифметики чисел является неустранимой. Невозможно писать качественный код, не зная и не думая об этом.
Что думаете об этом?