Сравнение разных типов данных в Go (golang). Зачем в Go неявные преобразования?

Рейтинг: 5Ответов: 1Опубликовано: 17.07.2023

Читаю Head First Go,наткнулся на с 56 на такое: введите сюда описание изображения Попробовал, действительно выдаёт ошибку:

    var fl float64 = 5.5
    var in int = 5
    if(fl > in){
        fmt.Println("vars")
    }

А потом попробовал так и всё сработало:

    if(5.5 > 5){
        fmt.Println("numbers")
    }

Если в go нельзя сравнить разные типы, то почему можно сделать так как на втором примере? У меня пока ответ один - наверное это неявные преобразования. Зачем их оставили в golang, если писался язык максимально простым и очевидным для чтения? Это как-то отходит от философии и концепции языка. Но раз уж оставили, значит зачем-то это надо, значит есть этому применение. Зачем - я пока не придумал, жду вашей помощи:)

Ответы

▲ 7Принят

ИМХО, кто-то из разработчиков Go был большим поклонником языка Ada, где от компилятора потребовали реализовать почти неограниченную точность для compile-time вычислений. В спецификации Go от компилятора тоже захотели неограниченную точность вычислений:

Numeric constants represent exact values of arbitrary precision and do not overflow.

В силу этого требования литеральная константа 5 не является объектом типа int. Это репрезентация абстрактного математического понятия число пять. Поэтому его вполне возможно сравнивать с литеральной константой 5.5, которая, в свою очередь, выражает математическую абстракцию пять целых пять десятых.

Для того, чтобы не упираться в 64-битную целую арифметику создатели Go постановили считать константы без типа (untyped). Редукция потенциально неограниченной константы до объекта, хранимого в конкретном типе, происходит только в момент использования в типизированном выражении (например, присваивании переменной или инициализации поля структуры).

The concept of untyped constants in Go means that all the numeric constants, whether integer, floating-point, complex, or even character values, live in a kind of unified space. It’s when we bring them to the computational world of variables, assignments, and operations that the actual types matter. But as long as we stay in the world of numeric constants, we can mix and match values as we like. All these constants have numeric value 1:

1
1.000
1e3-99.0*10-9
'\x01'
'\u0001'
'b' - 'a'
1.0+3i-3.0i

Because in Go, numeric constants work as you expect: like numbers.

https://go.dev/blog/constants