Go — строго типизированный язык, а это означает, что разработчик в любой момент должен точно знать, с каким типом значения он имеет дело. Например, если у нас есть функция, которая печатает строку, мы не можем просто дать ей целое число и ожидать, что она сработает. Мы должны явно привести его к строке:
func main() {
num := 5
numString string(num)
printString(numString)
}
func printString(s string) {
fmt.Println(s)
}
Если мы не приведем значение, компилятор go даже не позволит нам скомпилировать программу.
Динамическая типизация работает медленно
Разработчиков, пришедших из языков с динамической типизацией, часто раздражает строгая типизация Go. Они считают, что компилятор должен просто знать, что они означают, и выполнять приведение типа неявно.
Языки со строгой типизацией не будут угадывать за вас. Они заставляют вас принимать решения.
Нажмите, чтобы твитнуть
Для этого есть причина. Преобразование типов требует времени и ресурсов. Если бы среда выполнения Go динамически вводила каждое значение, то программы в целом работали бы намного медленнее.
Если вам нужны медленные программы, вернитесь к Python или Javascript.
Нажмите, чтобы твитнуть
Строгая типизация является явной
Помимо того, что строгая типизация работает быстрее, строгая типизация позволяет разработчику точно знать, с каким типом значения он имеет дело. Я не могу сказать вам, сколько раз в Python мне приходилось запускать программу и распечатывать тип объекта. (Глядя на тебя, NumPy)
Строгая типизация экономит память
В одном из наших рабочих приложений мы хранили в памяти миллионы целых. На 64-разрядных машинах это означает, что мы сохраняли 64 бита для каждого целого числа, когда в действительности хранимое целое число никогда не превышало 10. Путем замены ints на uint8s мы сэкономили 80% памяти, которую использовало наше приложение. Парень, оплачивающий наш счет за облако, был очень доволен этим.
Хотя изменение типов int и float может сэкономить память, остерегайтесь таких оптимизаций. Программу может стать довольно трудно читать, если каждая вторая строка:
toRound := float64(someNumber)
toSave := float32(toRound)
Правда в том, что большинство стандартных библиотечных функций и популярных пакетов (и, надеюсь, то, что вы пишете тоже) используют размеры по умолчанию. Например, math.Round использует float64s, а time.AddDate использует целые числа. Если экономия памяти не является значительной, обычно лучше придерживаться обычного.
Интерфейсы — не утиные типы
Интерфейсы допускают своего рода полиморфизм в Go. Их цель не в том, чтобы дать разработчикам возможность внедрить динамическую типизацию в язык. Я видел, как разработчики делали такие вещи, как:
func jsonToDynamic(dat []byte) {
m := map[string]interface{}{}
json.Unmarshal(dat, &m)
// do something with m["hello"]
}
Я смиренно спрашиваю… ПОЧЕМУ? При распаковке JSON в 99% случаев мы должны знать форму объекта. Если мы знаем форму объекта, то мы должны выполнить демаршалирование в структуру, в которой объявлен тип каждого поля. Мы даже получим красивую ошибку немаршалирования, если форма искажена.
Спасибо за чтение
Напишите мне в твиттере @wagslane, если у вас есть какие-либо вопросы или комментарии.
Следите за мной на Dev.to: wagslane
Пост Преобразование Golang — Ints To Strings And Strong Typing впервые появился на Qvault.