Нажмите "Enter" для перехода к содержанию

3 наиболее распространённых подводных камня в Go

0

Начнем программирование на Go с основ. Функция range является одной из самых используемых в Go. Вот пример использования (не обращайте внимания, что мы присваиваем всем животным в зоопарке 999 ног):

Вышеприведённый код выглядит довольно невинно. Однако вы можете удивиться, узнав, что два fmt.Printf() выражения дают одинаковые результаты.

Подводный камень

Значения (хранятся как animal ), по которым мы проходимся с помощью range , являются не указателями на значения, а копиями значений из zoo .

Решение

Чтобы изменить элемент массива, мы должны изменить этот элемент через указатель:

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

Быть может, вы использовали “…” в ЯП С для создания вариативной функции; вариативная функция – это функция, принимающая переменное количество аргументов.

В C вы должны последовательно вызвать макрос va_arg для доступа к необязательным аргументам. И, если вы попытаетесь использовать вариативный аргумент любым другим способом, компилятор выдаст ошибку.

Программирование на Go задает несколько иные правила. В Golang это выглядит так же, как и в С, но работает по-другому. Здесь представлена вариативная функция myFprint . Обратите внимание, как используется вариативный аргумент a :

Можно подумать, что компилятор выдал бы ошибку при неправильном использовании вариативных параметров. Но обратите внимание, как fmt.Sprintf без нареканий использовал первый аргумент в a .

Подводный камень

В Go вариативные параметры разделяются компилятором.

Это означает, что вариативный аргумент a – на самом деле отдельная переменная. Поэтому приведённый ниже код действителен:

Продолжим изучение Go слайсингом. Если вы делали слайсинг в Python, то наверняка помните, что этот приём даёт вам новый список со ссылками на элементы. Это свойство позволяет использовать такой Python код:

Если вы попробуете то же самое в Go, получите что-то другое:

Подводный камень

В Go слайс имеет тот же базовый массив и ёмкость, что и оригинал. В Golang если вы измените элемент в слайсе, исходное содержимое тоже будет изменено.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *