Примечания к выпуску Go 1.6

Введение в Go 1.6

Последний выпуск Go, версия 1.6, появился через шесть месяцев после 1.5. Большинство изменений касаются реализации языка, среды выполнения и библиотек. Языковая спецификация не изменилась. Как и всегда, выпуск сохраняет обещание совместимости Go 1. Ожидается, что почти все программы на Go продолжат компилироваться и выполняться так же, как и раньше.

В этом выпуске добавлены новые порты для Linux на 64-битном MIPS и Android на 32-битном x86; определены и применены правила для совместного использования указателей Go с C; прозрачная, автоматическая поддержка HTTP/2; и новый механизм для повторного использования шаблонов.

Изменения в языке

В этом выпуске нет изменений в языке.

Порты

Go 1.6 добавляет экспериментальные порты для Linux на 64-битном MIPS (linux/mips64 и linux/mips64le). Эти порты поддерживают cgo, но только с внутренней компоновкой.

Go 1.6 также добавляет экспериментальный порт для Android на 32-битном x86 (android/386).

В FreeBSD Go 1.6 по умолчанию использует clang вместо gcc в качестве внешнего C-компилятора.

В Linux на little-endian 64-битном PowerPC (linux/ppc64le), Go 1.6 теперь поддерживает cgo с внешней компоновкой и в целом является почти полнофункциональным.

В NaCl Go 1.5 требовал версию SDK pepper-41. Go 1.6 добавляет поддержку более поздних версий SDK.

В 32-битных системах x86, использующих режимы компиляции -dynlink или -shared, регистр CX теперь перезаписывается при определенных ссылках на память и должен быть избегаем вручную написанном ассемблере. См. документацию по ассемблеру для получения подробностей.

Инструменты

Cgo

В cgo внесено одно главное изменение и одно незначительное.

Главное изменение — это определение правил для совместного использования указателей Go с кодом на C, чтобы обеспечить совместную работу такого кода с garbage collector'ом Go. Кратко говоря, Go и C могут совместно использовать память, выделенную Go, когда указатель на эту память передается в C как часть вызова cgo, при условии, что сама память не содержит указателей на память, выделенную Go, и при условии, что C не сохраняет указатель после завершения вызова. Эти правила проверяются средой выполнения во время выполнения программы: если среда выполнения обнаруживает нарушение, она выводит диагностику и завершает программу. Проверки можно отключить, установив переменную окружения GODEBUG=cgocheck=0, но следует отметить, что подавляющее большинство кода, выявленного проверками, несовместимо с garbage collector'ом по какой-либо причине. Отключение проверок обычно приводит только к более загадочным сценариям сбоев. Лучше всего исправлять код, а не отключать проверки. См. документацию по cgo для получения дополнительной информации.

Незначительное изменение заключается в добавлении явных типов C.complexfloat и C.complexdouble, отдельных от Go-типами complex64 и complex128. Соответствующие друг другу числовые типы C и Go-типы комплексных чисел больше не являются взаимозаменяемыми.

Инструментарий компилятора

Инструментарий компилятора в основном не изменился. Внутри, наиболее значительным изменением стало то, что парсер теперь написан вручную, а не генерируется из yacc.

Компилятор, компоновщик и команда go имеют новый флаг -msan, аналогичный флагу -race и доступный только на linux/amd64, который включает взаимодействие с Clang MemorySanitizer. Такое взаимодействие полезно в основном для тестирования программы, содержащей подозрительный C или C++ код.

Компоновщик имеет новую опцию -libgcc, чтобы задать ожидаемое местоположение библиотеки поддержки компилятора C при компоновке кода cgo. Опция используется только при использовании -linkmode=internal, и может быть установлена в none, чтобы отключить использование библиотеки поддержки.

Реализация режимов сборки, начатая в Go 1.5, была расширена до большего числа систем. В этом релизе добавлена поддержка режима c-shared на android/386, android/amd64, android/arm64, linux/386 и linux/arm64; для режима shared на linux/386, linux/arm, linux/amd64 и linux/ppc64le; а также для нового режима pie (генерация исполняемых файлов, независимых от положения в памяти) на android/386, android/amd64, android/arm, android/arm64, linux/386, linux/amd64, linux/arm, linux/arm64 и linux/ppc64le. См. документацию по дизайну для получения подробной информации.

Напоминаем, что флаг -X компоновщика изменился в Go 1.5. В Go 1.4 и более ранних версиях он принимал два аргумента, как в

<code>-X importpath.name value
</code>

Go 1.5 добавила альтернативный синтаксис, использующий один аргумент, который сам по себе представляет собой пару name=value:

<code>-X importpath.name=value
</code>

В Go 1.5 старый синтаксис всё ещё принимался, после вывода предупреждения, предлагающего использовать новый синтаксис вместо него. Go 1.6 продолжает принимать старый синтаксис и выводить предупреждение. Go 1.7 удалит поддержку старого синтаксиса.

Gccgo

Расписания релизов проектов GCC и Go не совпадают. Релиз GCC 5 содержит версию gccgo Go 1.4. Следующий релиз, GCC 6, будет содержать версию gccgo Go 1.6.1.

Команда Go

Базовая операция команды go не изменилась, но есть несколько изменений, которые стоит отметить.

Go 1.5 представила экспериментальную поддержку vendoring (управления зависимостями), которая включается установкой переменной окружения GO15VENDOREXPERIMENT в значение 1. Go 1.6 сохраняет поддержку vendoring, которая больше не считается экспериментальной, и включает её по умолчанию. Её можно отключить явно, установив переменную окружения GO15VENDOREXPERIMENT в значение 0. Go 1.7 удалит поддержку переменной окружения.

Наиболее вероятная проблема, возникающая при включении vendoring по умолчанию, связана с исходными деревьями, содержащими существующую директорию с названием vendor, которая не предназначена для интерпретации согласно новым правилам vendoring. В этом случае простейшее решение — переименовать директорию в любое другое название, отличное от vendor, и обновить все затронутые пути импорта.

Для получения дополнительной информации о vendoring см. документацию команды go и документацию по дизайну.

Добавлен новый флаг сборки -msan, который позволяет компилировать Go с поддержкой LLVM memory sanitizer. Он предназначен в основном для использования при линковке с кодом на C или C++, который проверяется с помощью memory sanitizer.

Команда Go doc

Go 1.5 представила команду go doc, которая позволяет ссылаться на пакеты, используя только имя пакета, например: go doc http. В случае неоднозначности поведение Go 1.5 заключалось в использовании пакета с лексикографически минимальным путем импорта. В Go 1.6 неоднозначность разрешается путем предпочтения путей импорта с меньшим количеством элементов, при равенстве — с использованием лексикографического сравнения. Важным следствием этого изменения является то, что оригинальные копии пакетов теперь предпочитаются над vendored копиями. Успешные поиски также, как правило, выполняются быстрее.

Команда Go vet

Команда go vet теперь выявляет передачу значений функций или методов в качестве аргументов в Printf, например, когда передаётся f, хотя имелось в виду f().

Производительность

Как и всегда, изменения настолько общие и разнообразные, что точные утверждения о производительности сложно сделать. Некоторые программы могут работать быстрее, некоторые — медленнее. В среднем программы из тестовой сборки Go 1 работают немного быстрее в Go 1.6 по сравнению с Go 1.5. Периоды пауз сборщика мусора даже ниже, чем в Go 1.5, особенно для программ, использующих большое количество памяти.

Были проведены значительные оптимизации, приведшие к улучшению более чем на 10% в реализациях следующих пакетов: compress/bzip2, compress/gzip, crypto/aes, crypto/elliptic, crypto/ecdsa и sort.

Стандартная библиотека

HTTP/2

В Go 1.6 добавлена прозрачная поддержка нового HTTP/2 протокола в пакете net/http. Клиенты и серверы на Go будут автоматически использовать HTTP/2 при использовании HTTPS. Не существует экспортируемого API, специфичного для обработки деталей HTTP/2 протокола, так же, как и не существует экспортируемого API, специфичного для HTTP/1.1.

Программы, которым необходимо отключить HTTP/2, могут сделать это, установив Transport.TLSNextProto (для клиентов) или Server.TLSNextProto (для серверов) в непустую карту.

Программы, которым необходимо настроить специфичные для HTTP/2 детали протокола, могут импортировать и использовать golang.org/x/net/http2, в частности его функции ConfigureServer и ConfigureTransport.

Среда выполнения

Среда выполнения добавила легковесную, наилучшую по возможности проверку одновременного неправильного использования карт. Как и всегда, если одна горутина записывает в карту, никакая другая горутина не должна одновременно читать или записывать карту. Если среда выполнения обнаруживает такое состояние, она выводит диагноз и завершает работу программы. Самый простой способ узнать больше о проблеме — запустить программу под race detector, который более надежно определит состояние гонки и даст больше информации.

Для паник, завершающих работу программы, среда выполнения теперь по умолчанию выводит только стек вызовов текущей горутины, а не всех существующих горутин. Обычно только текущая горутина имеет значение для паники, поэтому исключение других значительным образом уменьшает нерелевантный вывод в сообщении о сбое. Чтобы увидеть стеки всех горутин в сообщениях о сбое, установите переменную окружения GOTRACEBACK в значение all или вызовите debug.SetTraceback до сбоя, а затем перезапустите программу. См. документацию среды выполнения для получения подробной информации.

Обновление: Неперехваченные паники, предназначенные для вывода состояния всей программы, например, при обнаружении таймаута или при явной обработке полученного сигнала, теперь должны вызывать debug.SetTraceback("all") перед возникновением паники. Поиск использования signal.Notify может помочь определить такой код.

В Windows программы на Go версии 1.5 и ранее принудительно устанавливали глобальное разрешение таймера Windows в 1 мс при запуске, вызывая timeBeginPeriod(1). Go больше не требует этого для хорошей производительности планировщика, и изменение глобального разрешения таймера вызвало проблемы на некоторых системах, поэтому вызов был удален.

При использовании флагов -buildmode=c-archive или -buildmode=c-shared для сборки архива или разделяемой библиотеки, обработка сигналов была изменена. В Go 1.5 архив или разделяемая библиотека устанавливали обработчик сигнала для большинства сигналов. В Go 1.6 будет установлен обработчик сигнала только для синхронных сигналов, необходимых для обработки panic среды выполнения в Go-коде: SIGBUS, SIGFPE, SIGSEGV. См. пакет os/signal для получения дополнительных сведений.

Reflect

Пакет reflect устранил долгосрочное несоответствие между toolchains gc и gccgo, касавшееся встроенных неэкспортируемых типов структур, содержащих экспортируемые поля. Код, который проходит по структурам данных с использованием отражения, особенно для реализации сериализации в духе пакетов encoding/json и encoding/xml, может потребовать обновления.

Проблема возникает при использовании отражения для прохода по встроенному полю типа структуры, содержащему экспортируемое поле. В этом случае reflect некорректно сообщало, что встроенное поле экспортируемое, возвращая пустой Field.PkgPath. Теперь оно корректно сообщает, что поле не экспортируемое, но игнорирует это при оценке доступа к экспортируемым полям, содержащимся внутри структуры.

Обновление: Обычно код, который ранее проходил по структурам и использовал

<code>f.PkgPath != ""
</code>

для исключения недоступных полей, теперь должен использовать

<code>f.PkgPath != "" && !f.Anonymous
</code>

Например, см. изменения в реализациях encoding/json и encoding/xml.

Сортировка

В пакете sort реализация функции Sort была переписана, чтобы выполнять примерно на 10% меньше вызовов методов Less и Swap интерфейса Interface, что приводит к общему уменьшению времени выполнения. Новый алгоритм выбирает другой порядок для значений, которые сравниваются как равные (те пары, для которых Less(i, j) и Less(j, i) возвращают false).

Обновление: Определение Sort не даёт никаких гарантий относительно конечного порядка равных значений, но новое поведение может всё же сломать программы, ожидающие определённого порядка. Такие программы должны либо уточнить реализацию Less, чтобы отражать желаемый порядок, либо переключиться на Stable, который сохраняет исходный порядок равных значений.

Этот текст описывает изменения в Go 1.6, включая новые функции, улучшения и исправления. Вот краткое содержание: ### Основные изменения: 1. **Регулярные выражения (`regexp`)**: - Добавлен метод `Copy()` для `Regexp`, который позволяет избежать конкуренции при использовании одного регулярного выражения в нескольких горутинах. 2. **Пакет `strconv`**: - Добавлены функции `IsGraphic`, `QuoteToGraphic`, `QuoteRuneToGraphic`, `AppendQuoteToGraphic`, `AppendQuoteRuneToGraphic` — аналоги существующих функций, но для "графических" символов (без пробелов). 3. **Пакет `time`**: - Функция `Parse` теперь более строгая: отклоняет даты, такие как 30 февраля, 31 апреля и т.д. 4. **Пакет `os/exec`**: - Метод `Output()` теперь возвращает часть стандартной ошибки (`stderr`) при неудачном выполнении команды, что полезно для отладки. 5. **Пакет `net/url`**: - Ужесточена проверка хостов: пробелы в имени хоста больше не допускаются. - Тип `Error` теперь реализует интерфейс `net.Error`. 6. **Пакет `os`**: - Функции `IsExist`, `IsNotExist`, `IsPermission` теперь корректно работают с `SyscallError`. 7. **Обработка `SIGPIPE`**: - На Unix-подобных системах при записи в разорванный пайп теперь генерируется сигнал `SIGPIPE` (если запись идет в stdout/stderr). - Старое поведение (10 записей подряд с генерацией сигнала) убрано. 8. **Пакет `path/filepath` (Windows)**: - Исправлена работа функции `Join` при относительных путях диска (например, `c:a` вместо `c:\a`). 9. **Пакет `testing`**: - Время выполнения теста, вызвавшего `t.Parallel()`, теперь включает время ожидания завершения других тестов. 10. **Пакет `text/template`**: - Добавлен новый тип `ExecError` для ошибок выполнения шаблона. - Метод `Funcs()` теперь проверяет корректность имен функций в `FuncMap`. 11. **Пакет `net/http/httptest`**: - `ResponseRecorder` теперь инициализирует заголовок `Content-Type` с использованием алгоритма определения типа содержимого сервера. 12. **Пакет `fmt` и `strconv`**: - Добавлены функции для работы с "графическими" символами. 13. **Пакет `net/http`**: - Улучшена обработка параллельных тестов. 14. **Другие мелкие изменения**: - Улучшения в обработке ошибок, уточнения в спецификациях, более строгая проверка входных данных. ### Заключение: Go 1.6 внесла множество улучшений, особенно в части безопасности, производительности и согласованности работы с системными вызовами и регулярными выражениями. Также были внесены изменения в обработку ошибок и улучшены инструменты для тестирования и отладки.
GoRu.dev Golang на русском

На сайте представлена адаптированная под русский язык документация языка программирования Golang