Примечания к выпуску Go 1.8
Введение в Go 1.8
Последний выпуск Go, версия 1.8, появился через шесть месяцев после Go 1.7. Большинство изменений касаются реализации инструментария, среды выполнения и библиотек. Существует два незначительных изменения в спецификации языка. Как и всегда, выпуск сохраняет обещание совместимости Go 1. Ожидается, что почти все программы на Go продолжат компилироваться и выполняться так же, как и раньше.
В выпуске добавлена поддержка 32-битного MIPS, обновлена внутренняя часть компилятора для генерации более эффективного кода, сокращены паузы GC за счёт удаления пересканирования стека в режиме stop-the-world, добавлена поддержка HTTP/2 Push, добавлена грациозная остановка HTTP, добавлена дополнительная поддержка контекста, включено профилирование мьютексов, и упрощена сортировка срезов.
Изменения в языке
При явном преобразовании значения из одной структуры в другую, начиная с Go 1.8, теги игнорируются. Таким образом, две структуры, отличающиеся только тегами, могут быть преобразованы друг в друга:
<code>func example() {
type T1 struct {
X int `json:"foo"`
}
type T2 struct {
X int `json:"bar"`
}
var v1 T1
var v2 T2
v1 = T1(v2) // теперь допустимо
}
</code>
Спецификация языка теперь требует, чтобы реализации
поддерживали экспоненты не более 16 бит в числовых константах с плавающей точкой. Это не влияет
на компиляторы gc и
gccgo, оба из которых по-прежнему поддерживают 32-битные экспоненты.
Платформы
Go теперь поддерживает 32-битный MIPS на Linux для как больших (big-endian)
(linux/mips), так и малых (little-endian) машин
(linux/mipsle), реализующих набор инструкций MIPS32r1 с FPU
или эмуляцией FPU в ядре. Обратите внимание, что многие распространённые маршрутизаторы на базе MIPS не имеют FPU и
используют прошивку, которая не включает эмуляцию FPU в ядре; Go не будет работать на таких устройствах.
В DragonFly BSD, Go теперь требует DragonFly 4.4.4 или новее.
В OpenBSD, Go теперь требует OpenBSD 5.9 или новее.
Поддержка сетевых функций в порте для Plan 9 теперь намного более полная и соответствует поведению Unix и Windows в части дедлайнов и отмены. Для требований к ядру Plan 9, см. страницу вики Plan 9.
Go 1.8 теперь поддерживает только OS X 10.8 или новее. Скорее всего, это последний выпуск Go, поддерживающий 10.8. Компиляция Go или запуск бинарных файлов на более старых версиях OS X не тестировалась.
Go 1.8 станет последним релизом, поддерживающим Linux на процессорах ARMv5E и ARMv6:
Go 1.9, вероятно, потребует ARMv6K (как в Raspberry Pi 1) или более поздней версии.
Чтобы определить, является ли система Linux ARMv6K или более поздней версией, выполните команду
“go tool dist -check-armv6k”
(для удобства тестирования также возможно просто скопировать команду dist в систему без установки полной копии Go 1.8)
и если программа завершится с выводом “ARMv6K supported.”, значит система реализует ARMv6K или более позднюю версию.
Go на неконтрольных системах ARM уже требует ARMv6K или более поздней версии.
zos теперь является допустимым значением для GOOS,
зарезервированным для операционной системы z/OS.
Известные проблемы
Известны некоторые нестабильности на FreeBSD и NetBSD, которые не были полностью поняты. Это может привести к сбоям программы в редких случаях. См. проблему 15658 и проблему 16511. Любая помощь в решении этих проблем будет признана.
Инструменты
Ассемблер
Для 64-битных систем x86 были добавлены следующие инструкции:
VBROADCASTSD,
BROADCASTSS,
MOVDDUP,
MOVSHDUP,
MOVSLDUP,
VMOVDDUP,
VMOVSHDUP, и
VMOVSLDUP.
Для 64-битных систем PPC были добавлены общие скалярные векторные инструкции:
LXS,
LXSDX,
LXSI,
LXSIWAX,
LXSIWZX,
LXV,
LXVD2X,
LXVDSX,
LXVW4X,
MFVSR,
MFVSRD,
MFVSRWZ,
MTVSR,
MTVSRD,
MTVSRWA,
MTVSRWZ,
STXS,
STXSDX,
STXSI,
STXSIWX,
STXV,
STXVD2X,
STXVW4X,
XSCV,
XSCVDPSP,
XSCVDPSPN,
XSCVDPSXDS,
XSCVDPSXWS,
XSCVDPUXDS,
XSCVDPUXWS,
XSCVSPDP,
XSCVSPDPN,
XSCVSXDDP,
XSCVSXDSP,
XSCVUXDDP,
XSCVUXDSP,
XSCVX,
XSCVXP,
XVCV,
XVCVDPSP,
XVCVDPSXDS,
XVCVDPSXWS,
XVCVDPUXDS,
XVCVDPUXWS,
XVCVSPDP,
XVCVSPSXDS,
XVCVSPSXWS,
XVCVSPUXDS,
XVCVSPUXWS,
XVCVSXDDP,
XVCVSXDSP,
XVCVSXWDP,
XVCVSXWSP,
XVCVUXDDP,
XVCVUXDSP,
XVCVUXWDP,
XVCVUXWSP,
XVCVX,
XVCVXP,
XXLAND,
XXLANDC,
XXLANDQ,
XXLEQV,
XXLNAND,
XXLNOR,
XXLOR,
XXLORC,
XXLORQ,
XXLXOR,
XXMRG,
XXMRGHW,
XXMRGLW,
XXPERM,
XXPERMDI,
XXSEL,
XXSI,
XXSLDWI,
XXSPLT, и
XXSPLTW.
Yacc
Инструмент yacc (ранее доступный посредством выполнения
«go tool yacc») был удалён.
Начиная с Go 1.7 он больше не использовался компилятором Go.
Он был перемещён в репозиторий «tools» и теперь доступен по адресу
golang.org/x/tools/cmd/goyacc.
Fix
Инструмент fix имеет новую фиксирующую «context»
для изменения импортов из «golang.org/x/net/context»
в «context».
Pprof
Инструмент pprof теперь может профилировать TLS-серверы
и пропускать проверку сертификатов, используя схему URL «https+insecure».
Вывод callgrind теперь имеет гранулярность на уровне инструкций.
Trace
Инструмент trace имеет новый флаг -pprof для
создания профилей блокировок и задержек, совместимых с pprof, на основе
трассировки выполнения.
События сборки мусора теперь отображаются более чётко в просмотрщике трассировки выполнения. Активность сборки мусора отображается в отдельной строке, а вспомогательные горутины GC аннотированы их ролями.
Vet
Инструмент Vet стал строже в некоторых аспектах и менее строгим там, где ранее вызывал ложноположительные результаты.
Теперь Vet проверяет копирование массива блокировок,
дублирующие теги JSON и XML в структурах,
теги структур, не разделённые пробелами,
отложенные вызовы Response.Body.Close HTTP-запроса
до проверки ошибок, а также индексированные аргументы в Printf.
Также улучшены существующие проверки.
Компилятор
Go 1.7 представила новый бэкенд компилятора для 64-битных систем x86. В Go 1.8 этот бэкенд был дополнительно развит и теперь используется для всех архитектур.
Новый бэкенд, основанный на форме статической однократной присваивания (SSA), генерирует более компактный и эффективный код и предоставляет лучшую платформу для оптимизаций, таких как удаление проверок границ. Новый бэкенд снижает время CPU, необходимое для наших тестовых программ, на 20–30% на 32-битных системах ARM. Для 64-битных систем x86, которые уже использовали бэкенд SSA в Go 1.7, прирост составляет более скромные 0–10%. Другие архитектуры, вероятно, увидят улучшения близкие к показателям 32-битных ARM.
Временный флаг компилятора -ssa=0, введённый в Go 1.7
для отключения нового бэкенда, был удалён в Go 1.8.
Помимо включения нового бэкенда компилятора для всех систем, Go 1.8 также представляет новый фронтенд компилятора. Новый фронтенд компилятора не должен быть заметен пользователям, но он является основой для будущей работы по производительности.
Компилятор и компоновщик были оптимизированы и работают быстрее в этом выпуске, чем в Go 1.7, хотя они всё ещё работают медленнее, чем хотелось бы, и будут продолжать оптимизироваться в будущих выпусках. По сравнению с предыдущим выпуском, Go 1.8 работает примерно на 15% быстрее.
Cgo
Инструмент Go теперь запоминает значение переменной окружения CGO_ENABLED, установленной во время make.bash, и применяет её ко всем последующим компиляциям по умолчанию, чтобы исправить проблему #12808.
При выполнении нативной компиляции обычно нет необходимости явно устанавливать переменную окружения CGO_ENABLED, так как make.bash автоматически определит правильное значение. Основной причиной явного установления переменной CGO_ENABLED является тот факт, что ваша среда поддерживает cgo, но вы явно не хотите использовать поддержку cgo. В этом случае, установите CGO_ENABLED=0 во время make.bash или all.bash.
Теперь переменная окружения PKG_CONFIG может использоваться для задания программы, которая будет обрабатывать директивы #cgo pkg-config. По умолчанию используется pkg-config, программа, использовавшаяся в предыдущих версиях. Это сделано с целью облегчения кросс-компиляции cgo-кода.
Инструмент cgo теперь поддерживает опцию -srcdir, которая используется командой go.
Если cgo-код вызывает C.malloc, и malloc возвращает NULL, программа теперь будет аварийно завершаться с ошибкой нехватки памяти.
C.malloc никогда не возвращает nil.
В отличие от большинства функций C, C.malloc не может использоваться в форме с двумя результатами, возвращающей значение errno.
Если cgo используется для вызова функции C, передающей указатель на C-объединение (union), и если C-объединение может содержать любые указательные значения, и если проверка указателей cgo включена (по умолчанию она включена), то значение объединения теперь проверяется на наличие указателей Go.
Gccgo
Из-за совпадения полугодового цикла релизов Go с годовым циклом релизов GCC, релиз GCC 6 содержит версию gccgo Go 1.6.1. Ожидается, что следующий релиз, GCC 7, будет содержать версию gccgo Go 1.8.
Стандартный GOPATH
Переменная окружения GOPATH теперь имеет значение по умолчанию, если она не установлена. По умолчанию она равна $HOME/go в Unix и %USERPROFILE%/go в Windows.
Go get
Команда “go get” теперь всегда учитывает переменные окружения HTTP-прокси, независимо от того, используется ли флаг -insecure. В предыдущих версиях флаг -insecure имел побочный эффект — не использовать прокси.
Go bug
Новая команда
“go bug”
запускает отчет об ошибке на GitHub с предварительно заполненной информацией о текущей системе.
Go doc
Команда
“go doc”
теперь группирует константы и переменные по их типу, следуя поведению
godoc.
Для улучшения читаемости вывода doc, каждая сводка элементов первого уровня гарантированно занимает одну строку.
Теперь можно запрашивать документацию для конкретного метода в определении интерфейса, как в
“go doc net.Conn.SetDeadline”.
Плагины
Go теперь предоставляет раннюю поддержку плагинов с режимом сборки “plugin” для генерации плагинов, написанных на Go, и новым пакетом plugin для загрузки таких плагинов во время выполнения. Поддержка плагинов доступна только в Linux. Пожалуйста, сообщайте о любых проблемах.
Среда выполнения
Живость аргументов
Сборщик мусора больше не считает аргументы живыми на протяжении всего выполнения функции. За дополнительной информацией и для того, как заставить переменную оставаться живой, см. функцию
runtime.KeepAlive,
добавленную в Go 1.7.
Обновление:
Код, который устанавливает финализатор для выделенного объекта, может потребовать добавления вызовов runtime.KeepAlive в функции или методы, использующие этот объект.
Ознакомьтесь с документацией KeepAlive и её примером для получения дополнительных сведений.
Неправильное использование карты в параллелизме
В Go 1.6 среда выполнения добавила лёгкую, оптимистичную проверку неправильного использования карт в параллелизме. В этом выпуске улучшена эта проверка с поддержкой обнаружения программ, которые одновременно записывают и итерируют по карте.
Как и всегда, если одна горутина записывает в карту, никакая другая горутина не должна читать (включая итерацию) или записывать в карту параллельно. Если среда выполнения обнаруживает это условие, она выводит диагноз и завершает программу. Лучший способ узнать больше о проблеме — запустить программу под детектором гонок, который более надёжно определит гонку и предоставит больше информации.
Документация MemStats
Тип runtime.MemStats
был более подробно задокументирован.
Производительность
Как всегда, изменения настолько общие и разнообразные, что точные утверждения о производительности сложно сделать. Большинство программ должны работать немного быстрее, благодаря ускорениям в сборщике мусора и оптимизациям в стандартной библиотеке.
Были проведены оптимизации реализаций в пакетах
bytes,
crypto/aes,
crypto/cipher,
crypto/elliptic,
crypto/sha256,
crypto/sha512,
encoding/asn1,
encoding/csv,
encoding/hex,
encoding/json,
hash/crc32,
image/color,
image/draw,
math,
math/big,
reflect,
regexp,
runtime,
strconv,
strings,
syscall,
text/template и
unicode/utf8.
Сборщик мусора
Времена пауз при сборке мусора должны быть значительно короче, чем в Go 1.7, как правило менее 100 микросекунд и часто до 10 микросекунд. См. документ об устранении остановки всех потоков при повторном сканировании стека для получения подробностей. Работа по этой теме продолжается в Go 1.9.
Defer
Накладные расходы на отложенные вызовы функций были уменьшены примерно в два раза.
Cgo
Накладные расходы на вызовы из Go в C были уменьшены примерно в два раза.
Стандартная библиотека
Примеры
Примеры были добавлены в документацию во многих пакетах.
Сортировка
Пакет sort теперь включает удобную функцию
Slice для сортировки среза,
используя меньше функцию.
Во многих случаях это означает, что создание нового типа сортировщика больше не требуется.
Также появились
SliceStable и
SliceIsSorted.
HTTP/2 Push
Пакет net/http теперь включает механизм
для отправки HTTP/2 server pushes из
Handler.
Аналогично существующим интерфейсам Flusher и Hijacker,
ResponseWriter
в HTTP/2 теперь реализует новый интерфейс
Pusher.
Плавное завершение работы HTTP-сервера
HTTP-сервер теперь поддерживает плавное завершение работы с использованием нового
Server.Shutdown
метода и немедленное завершение с помощью нового
Server.Close
метода.
Больше поддержки контекста
Продолжая адаптацию
context.Context
в стандартную библиотеку, Go 1.8 добавляет дополнительную поддержку контекста
в существующие пакеты:
- Новый
Server.Shutdownпринимает аргумент контекста. - В пакете database/sql были сделаны существенные дополнения с поддержкой контекста.
- Все девять новых методов
Lookupв новомnet.Resolverтеперь принимают контекст.
Профилирование конкурирующих мьютексов
Среда выполнения и инструменты теперь поддерживают профилирование мьютексов с конкуренцией.
Большинству пользователей будет полезно использовать новый флаг -mutexprofile
вместе с "go test",
а затем использовать pprof на результирующем файле.
Также доступна более низкоуровневая поддержка через новые
MutexProfile
и
SetMutexProfileFraction.
Известное ограничение для Go 1.8 заключается в том, что профиль сообщает только о конкуренции для
sync.Mutex,
а не для
sync.RWMutex.
Мелкие изменения в библиотеке
Как и всегда, в библиотеке были внесены различные мелкие изменения и обновления, сделанные с учетом гарантии совместимости Go 1. В следующих разделах перечислены видимые для пользователя изменения и дополнения. Оптимизации и мелкие исправления ошибок не перечисляются.
archive/tar
Реализация tar исправляет множество ошибок в крайних случаях формата файла.
Reader
теперь способен обрабатывать tar-файлы в формате PAX с записями размером более 8 ГБ.
Writer
больше не создает некорректные tar-файлы в некоторых ситуациях, связанных с длинными путями.
compress/flate
Были внесены некоторые мелкие исправления в кодировщике для улучшения
коэффициента сжатия в определенных ситуациях. В результате, точный
закодированный вывод DEFLATE может отличаться от Go 1.7. Поскольку
DEFLATE является базовым алгоритмом сжатия для gzip, png, zlib и zip,
эти форматы могут иметь измененные выходные данные.
Кодировщик, работающий в режиме
NoCompression,
теперь формирует согласованный вывод, который не зависит от размера срезов,
передаваемых в метод
Write.
Декодировщик, при обнаружении ошибки, теперь возвращает любые непрочитанные данные, которые он успел распаковать, вместе с ошибкой.
compress/gzip
Кодировщик Writer
теперь кодирует поле MTIME со значением ноль, если
поле Header.ModTime
имеет нулевое значение.
В предыдущих версиях Go кодировщик записывал бессмысленное значение.
Аналогично,
декодировщик Reader
теперь отчитывается о нулевом закодированном поле MTIME
как о нулевом значении Header.ModTime.
context
Ошибка DeadlineExceeded
теперь реализует интерфейс
net.Error
и возвращает значение true как для метода Timeout, так и для метода
Temporary.
crypto/tls
Новый метод
Conn.CloseWrite
позволяет закрывать TLS-соединение наполовину.
Новый метод
Config.Clone
выполняет клонирование конфигурации TLS.
Новый коллбэк
Config.GetConfigForClient
позволяет динамически выбирать конфигурацию для клиента, основываясь
на ClientHelloInfo клиента.
Структура ClientHelloInfo
теперь содержит новые поля: Conn, SignatureSchemes (используя
новый тип SignatureScheme),
SupportedProtos и SupportedVersions.
Новый коллбэк
Config.GetClientCertificate
позволяет выбирать клиентский сертификат на основе TLS-сообщения
CertificateRequest сервера, представленного новой структурой
CertificateRequestInfo.
Новое поле
Config.KeyLogWriter
позволяет отлаживать TLS-соединения
в WireShark
и подобных инструментах.
Новый
Config.VerifyPeerCertificate
коллбэк позволяет выполнять дополнительную проверку сертификата, предоставленного узлом.
Пакет crypto/tls теперь реализует базовые меры против(padding oracles) CBC. Не должно быть явных зависимостей от секретных значений по времени выполнения, однако он не пытается нормализовать доступ к памяти для предотвращения утечек времени выполнения через кэш.
Пакет crypto/tls теперь поддерживает X25519 и
ChaCha20-Poly1305.
ChaCha20-Poly1305 теперь имеет более высокий приоритет, если
не доступна поддержка аппаратного ускорения AES-GCM.
Также теперь поддерживается набор шифров AES-128-CBC с SHA-256, но отключен по умолчанию.
crypto/x509
Теперь поддерживаются подписи PSS.
UnknownAuthorityError
теперь имеет поле Cert, которое сообщает о ненадежном сертификате.
Валидация сертификатов стала более лояльной в некоторых случаях и строже в других.
Корневые сертификаты теперь также будут искаться в
/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
в Linux, чтобы обеспечить поддержку RHEL и CentOS.
database/sql
Пакет теперь поддерживает context.Context. Добавлены новые методы,
оканчивающиеся на Context, такие как
DB.QueryContext и
DB.PrepareContext,
принимающие аргументы контекста. Использование новых методов Context гарантирует,
что соединения закрываются и возвращаются в пул соединений по завершении запроса;
позволяет отменять выполняющиеся запросы при поддержке драйвером;
а также позволяет пулу баз данных отменять ожидание следующего доступного соединения.
IsolationLevel
теперь можно установить при запуске транзакции, указав уровень изоляции
в TxOptions.Isolation и передав его в
DB.BeginTx.
Если выбран уровень изоляции, который не поддерживается драйвером, будет возвращена ошибка.
Также можно установить атрибут только для чтения для транзакции, установив
TxOptions.ReadOnly
в true.
Запросы теперь предоставляют информацию о типе SQL-колонки для драйверов, которые поддерживают это.
Rows может возвращать ColumnTypes,
которые могут включать информацию о типе SQL, длину колонки и соответствующий тип Go.
Rows
теперь может представлять несколько наборов результатов. После того как
Rows.Next возвращает false,
можно вызвать Rows.NextResultSet
для перехода к следующему набору результатов. Существующий Rows
должен продолжать использоваться после перехода к следующему набору результатов.
NamedArg может использоваться
в качестве аргументов запроса. Новая функция Named
помогает более кратко создавать NamedArg.
Если драйвер поддерживает новый интерфейс
Pinger,
методы DB.Ping
и DB.PingContext
будут использовать этот интерфейс для проверки, действительно ли соединение с базой данных всё ещё активно.
Новые методы запросов с Context работают со всеми драйверами, но
отмена Context не будет отзывчивой, если драйвер не был обновлён
для использования этих методов. Остальные функции требуют поддержки драйвером
в пакете database/sql/driver.
Авторы драйверов должны ознакомиться с новыми интерфейсами.
Пользователи существующих драйверов должны ознакомиться с документацией
драйвера, чтобы узнать, какие функции он поддерживает, а также с документацией
по конкретным системам, если такая имеется.
debug/pe
Пакет был расширен и теперь используется
Go linker для чтения объектных файлов, сгенерированных gcc.
Новые поля File.StringTable
и Section.Relocs
обеспечивают доступ к строковой таблице COFF и пересылкам COFF.
Новое поле File.COFFSymbols
предоставляет низкоуровневый доступ к таблице символов COFF.
encoding/base64
Новый метод Encoding.Strict
возвращает Encoding, который заставляет декодер возвращать ошибку,
если последние биты заполнения не равны нулю.
encoding/binary
Read
и Write
теперь поддерживают булевы значения.
encoding/json
UnmarshalTypeError
теперь включает имя структуры и поля.
Значение nil Marshaler
теперь сериализуется как JSON null.
Значение RawMessage теперь
сериализуется так же, как и его указательный тип.
Marshal
сериализует числа с плавающей точкой с использованием того же формата, что и в ES6,
отдавая предпочтение десятичной (не экспоненциальной) записи для более широкого диапазона значений.
В частности, все целые числа с плавающей точкой до 264 форматируются
так же, как и эквивалентное представление int64.
В предыдущих версиях Go, при десериализации JSON null в
Unmarshaler
считалось операцией без действия; теперь метод UnmarshalJSON Unmarshaler
вызывается с JSON литералом null, и может определять семантику этого случая.
encoding/pem
Decode
теперь строго проверяет формат конечной строки.
encoding/xml
Unmarshal
теперь поддерживает шаблоны для сбора всех атрибутов с использованием нового
тега структуры ",any,attr".
expvar
Новые методы
Int.Value,
String.Value,
Float.Value и
Func.Value
сообщают текущее значение экспортированной переменной.
Новая
функция Handler
возвращает HTTP-обработчик пакета, чтобы разрешить его установку в
нестандартные расположения.
fmt
Scanf,
Fscanf и
Sscanf теперь
обрабатывают пробелы иначе и более последовательно, чем
в предыдущих версиях. См. документацию по сканированию
для получения дополнительных сведений.
go/doc
Новая функция IsPredeclared
сообщает, является ли строка предварительно объявленным идентификатором.
go/types
Новая функция
Default
возвращает тип по умолчанию для "нетипизированного" типа.
Выравнивание complex64 теперь соответствует
Go компилятору.
html/template
Пакет теперь проверяет
атрибут "type" тега
<script>.
image/png
Decode
(и DecodeConfig)
теперь поддерживают True Color и прозрачность в оттенках серого.
Encoder
теперь работает быстрее и создаёт меньший объём вывода
при кодировании изображений с палитрой.
math/big
Новый метод
Int.Sqrt
вычисляет ⌊√x⌋.
Новый метод
Float.Scan
является вспомогательной функцией для
fmt.Scanner.
Int.ModInverse
теперь поддерживает отрицательные числа.
math/rand
Новый метод
Rand.Uint64
возвращает значения типа uint64. Новый
Source64
интерфейс описывает источники, способные генерировать такие значения
напрямую; в противном случае метод Rand.Uint64
создаёт uint64 из двух вызовов метода
Int63 интерфейса Source.
mime
ParseMediaType
теперь сохраняет ненужные экранирования обратной косой черты как литералы,
чтобы поддержать MSIE.
Когда MSIE отправляет полный путь к файлу (в режиме "intranet"), он не экранирует
обратные косые черты: “C:\dev\go\foo.txt”, а не
“C:\\dev\\go\\foo.txt”.
Если мы видим ненужное экранирование обратной косой черты, мы теперь предполагаем,
что оно от MSIE и должно быть интерпретировано как литеральная обратная косая черта.
Известные генераторы MIME не создают ненужных экранирований обратной косой черты
для простых символов, таких как цифры и буквы.
mime/quotedprintable
Парсинг в
Reader
был ослаблен в двух аспектах, чтобы принимать больше входных данных,
наблюдаемых в реальных условиях.
Во-первых, он принимает знак равенства (=), за которым не следуют
две шестнадцатеричные цифры, как литеральный знак равенства.
Во-вторых, он тихо игнорирует завершающий знак равенства в конце
закодированного входного потока.
net
Документация по интерфейсу Conn была обновлена с целью уточнения ожиданий от реализации интерфейса.
Обновления в пакете net/http зависят от соблюдения реализацией документированных требований.
Обновление: реализации интерфейса Conn должны проверить, что они соответствуют описанной семантике.
Пакет golang.org/x/net/nettest
будет использовать Conn и проверять, что он ведёт себя корректно.
Новый метод
UnixListener.SetUnlinkOnClose
устанавливает, должен ли файл сокета удаляться из файловой системы при закрытии слушателя.
Новый тип Buffers позволяет более эффективно записывать данные в сеть из нескольких непрерывных буферов в памяти.
На некоторых машинах, для определённых типов соединений, это оптимизируется в специфичную для операционной системы операцию пакетной записи (например, writev).
Новый тип Resolver осуществляет поиск имён и номеров
и поддерживает context.Context.
Dialer теперь имеет необязательное поле
Resolver.
Тип Interfaces теперь поддерживается на Solaris.
Go DNS resolver теперь поддерживает параметры «rotate» и «option ndots:0» из файла resolv.conf.
Параметр «ndots» теперь учитывается так же, как и в libresolve.
net/http
Изменения в сервере:
- Сервер теперь поддерживает graceful shutdown, упомянуто выше.
-
Serverдобавляет параметры конфигурацииReadHeaderTimeoutиIdleTimeoutи документируетWriteTimeout. -
FileServerиServeContentтеперь поддерживают HTTP-условные запросы с заголовкомIf-Match, в дополнение к предыдущей поддержкеIf-None-Matchдля ETags, правильно форматированных согласно RFC 7232, раздел 2.3.
Существует несколько новых возможностей, которые может выполнять Handler сервера:
-
Context, возвращаемый функциейRequest.Context, отменяется, если закрывается базовое соединениеnet.Conn. Например, если пользователь закрывает браузер посередине медленного запроса,Handlerтеперь может обнаружить, что пользователь ушёл. Это дополняет существующую поддержкуCloseNotifier. Эта функциональность требует, чтобы базовыйnet.Connреализовывал недавно уточнённую документацию интерфейса. -
Для отправки trailer-заголовков после того, как заголовки уже были записаны,
см. новый механизм
TrailerPrefix. -
Handlerтеперь может прервать ответ, вызвав панику с ошибкойErrAbortHandler. -
Запись нулевого количества байт в
ResponseWriterтеперь определена как способ проверить, был лиResponseWriterперехвачен (hijacked): в этом случаеWriteвозвращаетErrHijacked, не записывая ошибку в журнал ошибок сервера.
Изменения клиента и транспорта:
-
Clientтеперь копирует большинство заголовков запроса при перенаправлении. См. документацию по типуClientдля получения подробной информации. -
Transportтеперь поддерживает международные доменные имена. Соответственно, это поддерживает Get и другие вспомогательные функции. -
Clientтеперь поддерживает перенаправления 301, 307 и 308. Например,Client.Postтеперь следует за перенаправлениями 301, преобразуя их вGETзапросы без тела, как это было ранее для ответов перенаправлений 302 и 303.Clientтеперь также следует за перенаправлениями 307 и 308, сохраняя исходный метод запроса и его тело, если оно есть. Если перенаправление требует повторной отправки тела запроса, запрос должен иметь определенное новое полеRequest.GetBody.NewRequestавтоматически устанавливаетRequest.GetBodyдля общих типов тела. -
Transportтеперь отклоняет запросы к URL-адресам с портами, содержащими символы, не являющиеся цифрами. -
Transportтеперь будет повторять неидемпотентные запросы, если до сбоя сети не было записано ни одного байта, и запрос не имеет тела. -
Новый
Transport.ProxyConnectHeaderпозволяет настраивать значения заголовков, отправляемых прокси при запросеCONNECT. -
DefaultTransport.Dialerтеперь включает поддержкуDualStack("Happy Eyeballs"), что позволяет использовать IPv4 в качестве резервного варианта, если, похоже, IPv6 не работает. -
Transportбольше не читает байт из ненулевогоRequest.Body, когдаRequest.ContentLengthравен нулю, чтобы определить, действительно лиContentLengthравен нулю или просто не определён. Чтобы явно указать, что тело имеет нулевую длину, либо установите его вnil, либо установите новое значениеNoBody. Новое значениеNoBodyпредназначено для использования функциями-конструкторамиRequest`; оно используетсяNewRequest.
net/http/httptrace
Теперь поддерживается трассировка TLS-рукопожатий клиентского запроса с помощью новых
ClientTrace.TLSHandshakeStart
и
ClientTrace.TLSHandshakeDone.
net/http/httputil
У ReverseProxy появился новый необязательный хук,
ModifyResponse,
который позволяет изменять ответ от бэкенда до его пересылки клиенту.
net/mail
Пустые закавыченные строки снова разрешены в части имени адреса.
То есть, Go 1.4 и более ранние версии принимали
"" <gopher@example.com>,
но в Go 1.5 была введена ошибка, из-за которой такой адрес отклонялся.
Теперь такой адрес снова распознаётся.
Метод
Header.Date
всегда предоставлял способ для разбора заголовка Date:.
Новая функция
ParseDate
позволяет разбирать даты, найденные в других строках заголовков, например, в заголовке Resent-Date:.
net/smtp
Если реализация метода
Auth.Start
возвращает пустое значение toServer,
пакет больше не отправляет завершающий пробел в команде SMTP AUTH,
что некоторые серверы отвергали.
net/url
Новые функции
PathEscape
и
PathUnescape
похожи на функции для экранирования и деэкранирования query, но предназначены для элементов пути.
Новые методы
URL.Hostname
и
URL.Port
возвращают поля hostname и port URL,
корректно обрабатывая случай, когда порт может отсутствовать.
Существующий метод
URL.ResolveReference
теперь правильно обрабатывает пути с экранированными байтами, не теряя экранирование.
Тип URL теперь реализует
encoding.BinaryMarshaler и
encoding.BinaryUnmarshaler,
что позволяет обрабатывать URL в данных gob.
Согласно RFC 3986,
Parse
теперь отклоняет URL вроде this_that:other/thing, вместо того чтобы интерпретировать их как относительные пути (так как this_that не является допустимой схемой).
Чтобы принудительно интерпретировать такой URL как относительный путь,
он должен быть префиксирован «./».
Метод URL.String теперь вставляет этот префикс при необходимости.
os
Функция
Executable возвращает
путь к выполняемому файлу.
Попытка вызвать метод на
os.File, который уже был закрыт, теперь возвращает новое значение ошибки
os.ErrClosed.
Ранее возвращалась системно-зависимая ошибка, например
syscall.EBADF.
В Unix-системах, os.Rename
теперь возвращает ошибку при переименовании каталога в существующий пустой каталог.
Ранее операция завершалась неудачей при переименовании в непустой каталог,
но завершалась успешно при переименовании в пустой каталог.
Это делает поведение в Unix соответствующим поведению других систем.
В Windows, длинные абсолютные пути теперь прозрачно преобразуются в расширенные пути (пути, начинающиеся с “\\?\”).
Это позволяет пакету работать с файлами, имена путей которых длиннее 260 символов.
В Windows, os.IsExist
теперь возвращает true для системной ошибки
ERROR_DIR_NOT_EMPTY.
Это примерно соответствует существующей обработке Unix-ошибки
ENOTEMPTY.
В Plan 9, файлы, которые не обслуживаются #M, теперь
будут иметь установленный флаг ModeDevice в
значении, возвращаемом функцией
FileInfo.Mode.
path/filepath
Исправлено несколько ошибок и граничных случаев в Windows:
Abs теперь вызывает Clean согласно документации,
Glob теперь соответствует шаблону
“\\?\c:\*”,
EvalSymlinks теперь
корректно обрабатывает “C:.”, и
Clean теперь правильно
обрабатывает начальный “..” в пути.
reflect
Добавлена новая функция
Swapper для поддержки sort.Slice.
strconv
Функция
Unquote теперь удаляет символы возврата каретки (\r)
в обратных кавычках (raw strings), следуя
семантике языка Go.
syscall
Функция
Getpagesize
теперь возвращает размер системы, а не константное значение.
Ранее она всегда возвращала 4KB.
Подпись функции Utimes была изменена в Solaris для соответствия подписи всех остальных систем Unix. Портативный код должен продолжать использовать os.Chtimes.
Поле X__cmsg_data было удалено из Cmsghdr.
text/template
Template.Execute теперь может принимать reflect.Value в качестве аргумента данных, а функции из FuncMap также могут принимать и возвращать reflect.Value.
time
Новая функция Until дополняет аналогичную функцию Since.
ParseDuration теперь принимает длинные дробные части.
Parse теперь отклоняет даты до начала месяца, например, 0 июня; она уже отклоняла даты после конца месяца, такие как 31 июня и 32 июля.
База данных tzdata была обновлена до версии 2016j для систем, которые ещё не имеют локальной базы данных часовых поясов.
testing
Новый метод T.Name (и B.Name) возвращает имя текущего теста или бенчмарка.
Новая функция CoverMode сообщает режим покрытия тестами.
Тесты и бенчмарки теперь помечаются как неудавшиеся, если включён детектор гонок и произошла гонка данных во время выполнения. Ранее отдельные тестовые случаи казались успешными, а неудачным было только общее выполнение тестовой программы.
Подпись функции MainStart была изменена, как разрешено документацией. Это внутренняя деталь и не входит в обязательства совместимости Go 1. Если вы не вызываете MainStart напрямую, но видите ошибки, это, вероятно, означает, что вы установили пустую переменную окружения GOROOT, которая не соответствует версии исполняемого файла команды go.
unicode
SimpleFold теперь возвращает свой аргумент без изменений, если предоставленный ввод был недопустимым рунным значением. Ранее реализация завершалась с ошибкой проверки выхода за пределы индекса.