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.