Channel: Go Update
Опросы в канале, да или нет?
Там ко мне пришлис рекламой с предложением разместить опрос. Я обычно никакие опросы никогда сам не прохожу (кроме Go Developer Survey), поэтому оставляю решение за аудиторией. Как проголосуете, так и будем делать.
П.С. Рекламы не будет. Точно. Не сейчас, не потом.
Там ко мне пришли
П.С. Рекламы не будет. Точно. Не сейчас, не потом.
Опрос
Тут это, ребята из DevCrowd проводят исследование среди Go-разработчиков:
- Какие навыки для go-разработчиков самые важные
- Какие инструменты используются в работе
- Как попадают в профессию и куда из нее уходят
- Полезные для развития каналы, курсы и книги
Предлогаю пройти опрос, рассказать про ваш опыт и помочь сделать исследование максимально охватным. Его результаты будут в открытом доступе, и помогут нам всем сравнить свои ожидания от коллег по Go с рыночными, построить план, что нужно изучить, и просто понять, что происходит с индустрией!
Пройти опрос можно тут.
Тут это, ребята из DevCrowd проводят исследование среди Go-разработчиков:
- Какие навыки для go-разработчиков самые важные
- Какие инструменты используются в работе
- Как попадают в профессию и куда из нее уходят
- Полезные для развития каналы, курсы и книги
Предлогаю пройти опрос, рассказать про ваш опыт и помочь сделать исследование максимально охватным. Его результаты будут в открытом доступе, и помогут нам всем сравнить свои ожидания от коллег по Go с рыночными, построить план, что нужно изучить, и просто понять, что происходит с индустрией!
Пройти опрос можно тут.
survey.alchemer.eu
Исследование рынка Go-разработчиков, 2023
Исследование рынка Go-разработчиков, 2023.
proposal: math/rand/v2 — первый v2 пакет в стандартной библиотеке
Расс Кокс предлагает добавить в std новый пакет, который должен стать заменой существующему
Его ключевые особенности:
— Уберут метод
— Уберут
— У
— Будут проведены различные оптимизации существующих методов.
— Добавят дженерик функцию аля
— Новая реализация
Главная мотивация, кроме улучшения самого генератора, это показать как именно v2 пакеты должны в будущем выглядеть в стандартной библиотеке. Как с ними должен будет работать тулинг и средства документации. Расс утверждает, что это будет хорошая подготовка перед началом работы над возможными
Расс Кокс предлагает добавить в std новый пакет, который должен стать заменой существующему
math/rand
.Его ключевые особенности:
— Уберут метод
Rand.Read
и функцию Read
. Аргументируют тем, что использование псевдослучайных чисел для генерации последовательностей из байт это почти всегда плохая идея. Более того, очень часто IDE подхватывает math/rand.Read
когда должен подхватить crypto/rand.Read
.— Уберут
Source.Seed
, Rand.Seed
, и функцию Seed
. Глобальный Seed
и так deprecated начиная с Go 1.20, а Source.Seed
, Rand.Seed
подразумевают, что зерно всегда имеет тип int64
, что не всех случаях так. Плюс отсутствие функции Seed
приведет к тому, что общий генератор случайных чисел будет всегда проинициализирован самим Go. Это позволит безболезненно менять алгоритм генерации случайных чисел глобальными функциями, не ломая обратную совместимость.— У
Source
интерфейса изменят сигнатуру метода с Int63() int64
на Uint64() uint64
. По этой же причине уберут интерфейс Source64
.— Будут проведены различные оптимизации существующих методов.
— Добавят дженерик функцию аля
rand.N[V Number](v V)
которая позволит легче работать с своими типами. Как пример: rand.N(1*time.Minute)
где возвращаемое не нужно будет приводить к time.Duration
.— Новая реализация
Source
— PCG-DXSM, генератор который и быстрее и занимает меньше памяти. Судя по предварительному API состояние генератора можно будет сохранять и восстанавливать из слайса байт.Главная мотивация, кроме улучшения самого генератора, это показать как именно v2 пакеты должны в будущем выглядеть в стандартной библиотеке. Как с ними должен будет работать тулинг и средства документации. Расс утверждает, что это будет хорошая подготовка перед началом работы над возможными
sync/v2
и encoding/json/v2
. Во вторых v2 позволяют показать преемственность пакетов и тот факт, что это не дизайн API с нуля, а набор изменений оригинального дизайна, где каждое изменение имеет под собой большое число факторов в свою пользу.GitHub
math/rand/v2: revised API for math/rand · Issue #61716 · golang/go
Based on earlier discussions in #60751, #26263, and #21835, as well as discussions with @robpike, I propose adding a new version of math/rand, imported as math/rand/v2, to the standard library. The...
Дайджест активных предложений и дискуссий Go Core Team:
- ⌛✅ spec: add untyped builtin zero: почти принят, о нем можно почитать тут.
- ⌛proposal: time: stop requiring Timer/Ticker.Stop for prompt GC: облегчающее жизнь изменение. Теперь не нужно вызывать
- ⌛proposal: testing: add identity function that forces evaluation for benchmarks: бенчмарки пытаются научить не оптимизировать код внутри самого цикла бенчмарка. Иначе результаты могут показывать совсем не то, что вы думаете.
- ⌛proposal: cmd/compile: add new range behind GOEXPERIMENT=range:
- ✅ maps: remove Keys and Values for Go 1.21: из будущего пакета
- ❌ maps: remove package for Go 1.21: а вот сам пакет мы убирать не будем, много в нем хорошего и кроме тех двух функций.
Полный список - тут.
- ⌛✅ spec: add untyped builtin zero: почти принят, о нем можно почитать тут.
- ⌛proposal: time: stop requiring Timer/Ticker.Stop for prompt GC: облегчающее жизнь изменение. Теперь не нужно вызывать
Stop
у таймера, что-бы его собрал сборщик мусора до истечения этого самого таймера. А это значит код типо case <- time.After(time.Minute):
больше не приводит к утечкам, которые заметны на нагруженных местах.- ⌛proposal: testing: add identity function that forces evaluation for benchmarks: бенчмарки пытаются научить не оптимизировать код внутри самого цикла бенчмарка. Иначе результаты могут показывать совсем не то, что вы думаете.
- ⌛proposal: cmd/compile: add new range behind GOEXPERIMENT=range:
range
над кастомными функциями идет в main бранч и будет скрыт под флагом.- ✅ maps: remove Keys and Values for Go 1.21: из будущего пакета
maps
удалили две функции которые позволяли получить слайс ключей и слайс значений. Аргументируют, что в 1.22 завезут итераторы и хотят красивые имена сохранить для них.- ❌ maps: remove package for Go 1.21: а вот сам пакет мы убирать не будем, много в нем хорошего и кроме тех двух функций.
Полный список - тут.
Telegram
Go Update
Предопределенный идентификатор zero - универсальное нулевое значение для возврата и сравнений.
Тем времени поезд нововведений от Расса и не думает останавливаться. Вообще это предложение уже высказывалось много раз, но только после прихода дженериков стало…
Тем времени поезд нововведений от Расса и не думает останавливаться. Вообще это предложение уже высказывалось много раз, но только после прихода дженериков стало…
Релиз Go 1.21
Вот и состоялся релиз новой версии Go. Кроме того, что указано здесь, у нас так-же появились:
- Довольной большой пакет slices: среди прочего содержит функции Min / Max, функцию сортировки и функцию поиска в сортированном слайсе. И больше не нужно писать страшные блоки вставки и удаления элементов из слайса.
- Пакет maps: по сравнению со слайсами как-то бедновато, но есть удобная функция копирования.
- Пакет cmp: содержит обьявление всех сравниваемых по порядку типов и две базовые функции для работы с ними. Нужно скорее для пакетов maps и slices, а так-же разработчикам библиотек с коллекциями.
- Profile-guide optimization (PGO - оптимизация основанная на данных профилировки) вышла из превью и теперь применяется всегда если присутствует файл
- Улучшение пакета context: теперь можно вешать функцию на отмену контекста (удобно когда вам нужно закрыть канал или прекратить чтение из сокета) и отвязать дочерний контекст от отмены родителя.
- При выводе очень глубоких стеков теперь показывают 50 самых верхних и 50 самых нижних фреймов (названий функции) вместо 100 самых верхних как это было ранее. Должно помочь с отладкой паник в рекурсивных функциях.
Вот и состоялся релиз новой версии Go. Кроме того, что указано здесь, у нас так-же появились:
- Довольной большой пакет slices: среди прочего содержит функции Min / Max, функцию сортировки и функцию поиска в сортированном слайсе. И больше не нужно писать страшные блоки вставки и удаления элементов из слайса.
- Пакет maps: по сравнению со слайсами как-то бедновато, но есть удобная функция копирования.
- Пакет cmp: содержит обьявление всех сравниваемых по порядку типов и две базовые функции для работы с ними. Нужно скорее для пакетов maps и slices, а так-же разработчикам библиотек с коллекциями.
- Profile-guide optimization (PGO - оптимизация основанная на данных профилировки) вышла из превью и теперь применяется всегда если присутствует файл
default.pgo
в директории main
пакета. Говорят, что благодаря ей удалось ускорить компилятор примерно на 6%.- Улучшение пакета context: теперь можно вешать функцию на отмену контекста (удобно когда вам нужно закрыть канал или прекратить чтение из сокета) и отвязать дочерний контекст от отмены родителя.
- При выводе очень глубоких стеков теперь показывают 50 самых верхних и 50 самых нижних фреймов (названий функции) вместо 100 самых верхних как это было ранее. Должно помочь с отладкой паник в рекурсивных функциях.
go.dev
Go 1.21 Release Notes - The Go Programming Language
И снова про итераторы…
Если прошлое предложение от Расса показывало как будут выглядеть итераторы, то новое предложение показывает как мы будем ими пользоваться и готовит для этого огромный фундамент.
✅ У нас появятся новый пакет
✅ У нас будет четкий стандарт именования функций которые возвращают итераторы.
❗ Если итерация может провалится, правильным и идиоматичным типом итератора будет
❗ Нам дадут функцию для преобразования наших pull итераторов в push:
‼️ И главное: нам сразу подвезут кучу обновлений пакетов: strings, bytes, regexp а так-же обновления недавних slices и maps. Самих новых функций там очень много, судя по всему Расс учел опыт добавления дженериков, когда новую фичу привезли, а вот изменений в стандартную библиотеку под нее не привезли. Так же нас ждет пакет xiter (правда пока в exp модуле) которые даст большое число операций над этими самыми итераторами. Да-да ваши любимые
Сам proposal состоит из нескольких частей, там довольно много и подробно описано, поэтому если хотите вникнуть - рекомендую ознакомится с оригиналом. А сам релиз Go 1.22 похоже обещает быть не менее интересным чем релиз Go 1.18. Ждем…
Если прошлое предложение от Расса показывало как будут выглядеть итераторы, то новое предложение показывает как мы будем ими пользоваться и готовит для этого огромный фундамент.
✅ У нас появятся новый пакет
iter
и два новых типа: Seq[V any]
и Seq2[K, V any]
которые будут описывать итераторы. Общий тип просили в первом обсуждении итераторов.✅ У нас будет четкий стандарт именования функций которые возвращают итераторы.
❗ Если итерация может провалится, правильным и идиоматичным типом итератора будет
iter.Seq2[MyType, error]
. Соответсвенно каждый шаг сможет сам проверить себя на ошибку.❗ Нам дадут функцию для преобразования наших pull итераторов в push:
func iter.Pull(seq iter.Seq[K,V]) (func() (K, V), stop func())
которая возвращает функцию для получения следующего элемента из итератора и функцию для его остановки. Здесь Расс еще раз напоминает, что писать push итераторы проще, процесс подготовки к работе и очистки у них делается в рамках одного потока управления, а не в разных функциях. А чем проще, тем меньше шанс совершить ошибку.‼️ И главное: нам сразу подвезут кучу обновлений пакетов: strings, bytes, regexp а так-же обновления недавних slices и maps. Самих новых функций там очень много, судя по всему Расс учел опыт добавления дженериков, когда новую фичу привезли, а вот изменений в стандартную библиотеку под нее не привезли. Так же нас ждет пакет xiter (правда пока в exp модуле) которые даст большое число операций над этими самыми итераторами. Да-да ваши любимые
Map, Filter, Concat, Merge, Zip
— все это там будет.Сам proposal состоит из нескольких частей, там довольно много и подробно описано, поэтому если хотите вникнуть - рекомендую ознакомится с оригиналом. А сам релиз Go 1.22 похоже обещает быть не менее интересным чем релиз Go 1.18. Ждем…
GitHub
iter: new package for iterators · Issue #61897 · golang/go
We propose to add a new package iter that defines helpful types for iterating over sequences. We expect these types will be used by other APIs to signal that they return iterable functions. This is...
Персональная запись: сегодня мне исполнился 31 год.
Сегодня, как и в каждом году, в этот день и месяц, число прожитых мной лет снова сделало инкремент на единицу. Это будет небольшая персональная заметка о том, что было и возможно будет.
Идея вести такой список заметок по Go родилась спонтанно. Я довольно часто скидывал в чатики инфу про новые фичи или интересные, на мой взгляд, обсуждения в сообществе. Предложения от разработчиков языка, предложения от сообщества, тренд общей эволюции языка и свои, не редко критичные, мысли по этому поводу. Обьяснения зачем эти нововведения вообще нужны. После одного из таких сообщений, Коля Тузов (@justskiv) предложил мне начать вести блог, куда я буду структурированно это все писать. Структурированно требует сил и времени, это не напишешь в двух словах ибо нужно попытаться развить и обьяснить свою мысль. По этой причине я изначально отказывался.
Но потом, после очередного настойчивого предложения от Коли 😄, мне стало понятно, что число и смысл обсуждений, за которыми я слежу, начинает выпадать из моей памяти. А главное выпадают мысли по поводу этих обсуждений и нововведений. И стало понятно, что ценность такого блога будет не только в том, что увидят другие, но и в том, что спустя время смогу увидеть я и вспомнить свои собственные мысли. Такие заметки на полях имеют ценность сами по себе. И я наконец решился…
Из других изменений: я недавно побывал в Чили. Про этот опыт мы скорее всего будем делать подкаст с Колей, вместе с обуждением работы над опенсорс проектом в распределенной команде — там есть о чем рассказать и подумать, как для тех кто думает о релокации, так и для тех кто считает что Латинская Америка это «апельсины, анаконда и амазонка».
Вообще отслеживание изменений это очень интересная штука. Когда я создавал этот канал, я думал тут будет максимум 100 подписчиков, так как тема довольно специфична. Как мне казалось большинству разработчиков вообще все равно, что там под капотом и куда движется сам язык (моя личная боль на собеседованиях). Однако нас уже больше 800 и восходящий тренд, судя по всему, не собирается останавливаться. За что отдельное спасибо всем и каждому из вас: если кто-то из вас узнал что-то новое для себя из моих записок, значит это все было не зря.
О будущем: в ноябре, если все пойдет нормально, я буду выступать на GolangConf 2023 с докладом про эволюцию языка, где я попытаюсь структурировать все те изменение которые мы видели за последние годы и так-же те изменения которые нам только предстоит увидеть. Попытаюсьповодить руками над прозрачным шаром вывести тренд. Язык действительно теряет частичку своей простоты, но я уверен, что мы по прежнему сможем найти тот баланс между простотой и удобством, которые находили все эти годы. Мы уже проходили все это с каналами и контекстами, сможем и тут.
А в заключении вот что: такая запись это исключение. Моей изначальной идеей был и остается строго технический канал который охватывает ядро языка и небольшую часть экосистемы вокруг. Уже существует достаточно каналов которые рассказывают про новые библиотеки или крутые истории от пользователей языка. А вести блог про свои мысли о реальности в целом я бы наверное не стал: уже и так есть большое число людей, которые транслируют поток своего мозга в интернет 24/7.
Но все же, как мне кажется, один раз в году можно сделать такое допущение. В конце концов, будет о чем подумать ровно через год, в этот день и месяц.
И конечно же: Show must go on…
Сегодня, как и в каждом году, в этот день и месяц, число прожитых мной лет снова сделало инкремент на единицу. Это будет небольшая персональная заметка о том, что было и возможно будет.
Идея вести такой список заметок по Go родилась спонтанно. Я довольно часто скидывал в чатики инфу про новые фичи или интересные, на мой взгляд, обсуждения в сообществе. Предложения от разработчиков языка, предложения от сообщества, тренд общей эволюции языка и свои, не редко критичные, мысли по этому поводу. Обьяснения зачем эти нововведения вообще нужны. После одного из таких сообщений, Коля Тузов (@justskiv) предложил мне начать вести блог, куда я буду структурированно это все писать. Структурированно требует сил и времени, это не напишешь в двух словах ибо нужно попытаться развить и обьяснить свою мысль. По этой причине я изначально отказывался.
Но потом, после очередного настойчивого предложения от Коли 😄, мне стало понятно, что число и смысл обсуждений, за которыми я слежу, начинает выпадать из моей памяти. А главное выпадают мысли по поводу этих обсуждений и нововведений. И стало понятно, что ценность такого блога будет не только в том, что увидят другие, но и в том, что спустя время смогу увидеть я и вспомнить свои собственные мысли. Такие заметки на полях имеют ценность сами по себе. И я наконец решился…
Из других изменений: я недавно побывал в Чили. Про этот опыт мы скорее всего будем делать подкаст с Колей, вместе с обуждением работы над опенсорс проектом в распределенной команде — там есть о чем рассказать и подумать, как для тех кто думает о релокации, так и для тех кто считает что Латинская Америка это «апельсины, анаконда и амазонка».
Вообще отслеживание изменений это очень интересная штука. Когда я создавал этот канал, я думал тут будет максимум 100 подписчиков, так как тема довольно специфична. Как мне казалось большинству разработчиков вообще все равно, что там под капотом и куда движется сам язык (моя личная боль на собеседованиях). Однако нас уже больше 800 и восходящий тренд, судя по всему, не собирается останавливаться. За что отдельное спасибо всем и каждому из вас: если кто-то из вас узнал что-то новое для себя из моих записок, значит это все было не зря.
О будущем: в ноябре, если все пойдет нормально, я буду выступать на GolangConf 2023 с докладом про эволюцию языка, где я попытаюсь структурировать все те изменение которые мы видели за последние годы и так-же те изменения которые нам только предстоит увидеть. Попытаюсь
А в заключении вот что: такая запись это исключение. Моей изначальной идеей был и остается строго технический канал который охватывает ядро языка и небольшую часть экосистемы вокруг. Уже существует достаточно каналов которые рассказывают про новые библиотеки или крутые истории от пользователей языка. А вести блог про свои мысли о реальности в целом я бы наверное не стал: уже и так есть большое число людей, которые транслируют поток своего мозга в интернет 24/7.
Но все же, как мне кажется, один раз в году можно сделать такое допущение. В конце концов, будет о чем подумать ровно через год, в этот день и месяц.
И конечно же: Show must go on…
📝 Изменение формата имени версий Go начиная с Go 1.21
Начиная с Go 1.21 любая версия Go теперь всегда именуется как Go
Проще всего понять на примерах:
→ Ранее Go 1.20 был и именем версии языка и именем первого релиза в ней. Т.е. для первого релиза
→ Начиная с Go 1.21 это только имя версии языка. Первый релиз в этой версии называется
Т.е. первый релиз в версии теперь всегда содержит в конце ноль.
А важно это по одной простой причине:
- Для первого релиза Go 1.20 была ссылка на скачивание https://storage.googleapis.com/golang/go1.20.linux-amd64.tar.gz
- ❗Для первого релиза Go 1.21 ссылка на скачивание стала https://storage.googleapis.com/golang/go1.21.0.linux-amd64.tar.gz а старый формат ссылки выдаст 404.
Не пропустите это когда будете обновлять ваши CI скрипты.
Начиная с Go 1.21 любая версия Go теперь всегда именуется как Go
x.yy.zz
взамен старого формата x.yy[.zz]
где .zz
не применялось для первого релиза внутри версии. Проще всего понять на примерах:
→ Ранее Go 1.20 был и именем версии языка и именем первого релиза в ней. Т.е. для первого релиза
go version
возвращал go version go1.20 linux/amd64
для второго релиза go version go1.20.1 linux/amd64
и так далее.→ Начиная с Go 1.21 это только имя версии языка. Первый релиз в этой версии называется
1.21.0
. Т.е. для первого релиза go version
возвращает go version go1.21.0 linux/amd64
для второго релиза go version go1.21.1 linux/amd64
и так далее.Т.е. первый релиз в версии теперь всегда содержит в конце ноль.
А важно это по одной простой причине:
- Для первого релиза Go 1.20 была ссылка на скачивание https://storage.googleapis.com/golang/go1.20.linux-amd64.tar.gz
- ❗Для первого релиза Go 1.21 ссылка на скачивание стала https://storage.googleapis.com/golang/go1.21.0.linux-amd64.tar.gz а старый формат ссылки выдаст 404.
Не пропустите это когда будете обновлять ваши CI скрипты.
… Оказывается Телеграм считает ветку комментариев к каждому сообщению в канале отдельно, а просто сообщения в общий чат идут отдельно, но сам общий чат содержит в себе все комментарии. Из-за этого часть моих ответов, которые были без цитирования, походу никто не увидел вообще, хах.
Ссылка на общий чат.
Ссылка на общий чат.
🟢 Быстрая установка нужной версии компилятора Go без замены текущей.
Раз пошло обсуждение о том, как установить Go 1.21 не удаляя старую (и без менеджеров пакетов) — на самом деле все довольно просто:
Для текущего мастера:
Полный список https://pkg.go.dev/golang.org/dl - там есть версии Go до 1.5 включительно.
Вот так легко можно поиграться с фичами Go которые еще находятся в разработке.
Раз пошло обсуждение о том, как установить Go 1.21 не удаляя старую (и без менеджеров пакетов) — на самом деле все довольно просто:
$ go install golang.org/dl/go1.21.0@latest
$ go1.21.0 download
$ go1.21.0 run main.go
Для текущего мастера:
$ go install golang.org/dl/gotip@latest
$ gotip download
$ gotip run main.go
Полный список https://pkg.go.dev/golang.org/dl - там есть версии Go до 1.5 включительно.
gotip
кстати умный - ему можно скормить бранч через gotip download BRANCHNAME
или конкретный CL (PR) через gotip download CL-NUMBER
. Номер всегда видно в конкретном ревью - например для https://go-review.googlesource.com/c/tools/+/518376/ комманда будет gotip download 518376
.Вот так легко можно поиграться с фичами Go которые еще находятся в разработке.
Улучшенный эскейп анализ для слайсов байт полученных из строк.
Из маленького, но приятного: наконец решили и закрыли одну из четырехзначных задач (сие значит очень старая задача, скорее всего еще из старого трекера) - #2205 read-only escape analysis and avoiding string -> []byte copies.
Допустим у вас есть код:
Сейчас вызов
По копии на каждую итерацию. А все из-за того, что при преобразовании из строки в слайс байт, эскейп анализ предполагает, что мы будем этот слайс байт по всякому редактировать. А раз строки у нас неизменяемые, то значит надо бы скопировать всю строку в новый слайс перед передачей его дальше в функцию. Это, в свою очередь, приводит к полной копии строки, что в чутких к производительности местах может быть довольно неприятно.
Однако уже в Go 1.22 эксейп анализ научится пробегать дерево вызываемых функций и пытаться доказать, что слайс байт мы все же не меняем (или эта строка нигде более не используется). И как следствие, копию можно уже не делать.
На
Никаких больше копий при конвертации из строки в слайс, если мы будем только читать из слайса.
Из маленького, но приятного: наконец решили и закрыли одну из четырехзначных задач (сие значит очень старая задача, скорее всего еще из старого трекера) - #2205 read-only escape analysis and avoiding string -> []byte copies.
Допустим у вас есть код:
package main
import (
"strings"
"testing"
)
var Index int
func BenchmarkStrToSlice(b *testing.B) {
someStr := strings.Repeat("HELLO WORLD", 6)
for i := 0; i < b.N; i++ {
Index = indexByte([]byte(someStr), 'D')
}
}
func indexByte(s []byte, c byte) int {
// Я про bytes.IndexByte(s, c) которая быстрее.
// Эта функция здесь находится для демонстрации.
for i, b := range s {
if b == c {
return i
}
}
return -1
}
Сейчас вызов
go test -benchmem -bench .
выдаст примерно такие результаты:BenchmarkStrToSlice-10
46341886
22.75 ns/op
80 B/op
1 allocs/op
По копии на каждую итерацию. А все из-за того, что при преобразовании из строки в слайс байт, эскейп анализ предполагает, что мы будем этот слайс байт по всякому редактировать. А раз строки у нас неизменяемые, то значит надо бы скопировать всю строку в новый слайс перед передачей его дальше в функцию. Это, в свою очередь, приводит к полной копии строки, что в чутких к производительности местах может быть довольно неприятно.
Однако уже в Go 1.22 эксейп анализ научится пробегать дерево вызываемых функций и пытаться доказать, что слайс байт мы все же не меняем (или эта строка нигде более не используется). И как следствие, копию можно уже не делать.
На
gotip test -benchmem -bench .
результаты обнадеживают:BenchmarkStrToSlice-10 248279863. 4.707 ns/op 0 B/op 0 allocs/op
Никаких больше копий при конвертации из строки в слайс, если мы будем только читать из слайса.
GitHub
cmd/compile: read-only escape analysis and avoiding string -> []byte copies · Issue #2205 · golang/go
Many functions take a []byte but only read from it. If the escape analysis code could flag parameters of a function as read-only, then code which passes in a []byte(string) conversion could be chea...
cmp: add Or
Недавно принятый небольшой proposal, не от авторов языка (что не такая уж и редкость), суть которого в очень простой функции — получение первого не пустого элемента из произвольного набора. Несмотря на то, что предложение кажется странным, подобная функция встречается достаточно часто на практике. Изначальный proposal был про получение первой не пустой строки из набора строк, но в итоге было решено сделать обобщенную функцию которая подходит для любых типов. И тут начались проблемы…
Я уже говорил о том, что proposal о
Ссылка для желающих поиграться на практике.
Недавно принятый небольшой proposal, не от авторов языка (что не такая уж и редкость), суть которого в очень простой функции — получение первого не пустого элемента из произвольного набора. Несмотря на то, что предложение кажется странным, подобная функция встречается достаточно часто на практике. Изначальный proposal был про получение первой не пустой строки из набора строк, но в итоге было решено сделать обобщенную функцию которая подходит для любых типов. И тут начались проблемы…
Я уже говорил о том, что proposal о
zero
ждут авторы кода с дженериками? Так вот это тот самый случай: сейчас cmp.Or
нельзя реализовать без использования констрейнта comparable
на дженериках. Который, в свою очередь, не работает с любыми типами внутри которых есть несравниваемые поля - например слайсы. А разгадка проста: для сравнения с нулем/пустой переменной сейчас авторы дженерик кода вынуждены создавать пустую переменную и проводить сравнивание с ней. Что довольно сильно ограничивает список типов с которыми такой код может работать.Ссылка для желающих поиграться на практике.
GitHub
cmp: add Or · Issue #60204 · golang/go
An extremely common string operation is testing if a string is blank and if so replacing it with a default value. I propose adding First(...strings) string to package strings (and probably an equiv...
🐞reflect: Value.IsZero should report true for negative zero
Довольно интересный баг в реализации
В Go 1.20 и 1.21 ответ будет true false
Реализация обработки чисел с плавающей точкой внутри
Баг уже исправлен и фикс будет включен в Go 1.22. Так как этот фикс приводит к изменению поведения его скорее всего не будет в багфиксах существующих релизов.
П.С: Про интересное скоро будет, мне пока чудовищно не хватает времени.
Довольно интересный баг в реализации
reflect.Value.IsZero
который происходит из попытки ответить на вопрос: а что выведет вот такой код?val := math.Copysign(0, -1) // Создаем float64(-0.0)
println(val == 0, reflect.ValueOf(val).IsZero())
Реализация обработки чисел с плавающей точкой внутри
IsZero
в версиях 1.21 и ниже вызывает функцию math.Float64bits
и затем сравнивает результат с 0
. Это верно для общего случая, но вот для числа -0
результат вызова этой функции будет совсем не 0
. При этом Go компилятор корректно обрабатывает такое сравнение в обычном коде, что и приводит к разным результатам.Баг уже исправлен и фикс будет включен в Go 1.22. Так как этот фикс приводит к изменению поведения его скорее всего не будет в багфиксах существующих релизов.
П.С: Про интересное скоро будет, мне пока чудовищно не хватает времени.
GitHub
reflect: Value.IsZero should report true for negative zero · Issue #61827 · golang/go
I discovered this while exploring #61372 (comment). In that comment, I asked whether v == zero is identical to reflect.ValueOf(&v).Elem().IsZero(). And the answer is unfortunately, "no&quo...
Про интересное: intern package proposal
Практически все разработчики сталкиваются с проблемой уникальности данных на уровне приложения. Чаще всего это вопрос удаления повтора строк, т.к. именно этот тип данных является самым «ходовым» в случае работы с хранилищами. А где хранилища, там и кеши и вопрос о затратах памяти. И рано или поздно, в любой достаточно сложной системе кеширования встает вопрос дедупликации - хранить повторяющиеся строки уж очень дорого на больших обьемах данных.
Неофиты спросят: «а в чем проблема? Почему нельзя использовать обычный словарь под мьютексом?». И ведь правда, мы можем использовать тип
В языках со сборщиком мусора, типо Java и C#, для решения этой проблемы есть специализированные типы (
Однако если чему-то сопротивляться, это не значит, что в этом чем-то пропадет потребность. Модуль go4.org/intern содержит в себе реализацию такой системы дедупликации значений. Авторами этого пакета являются разработчики Tailscale, часть из которых либо являлись частью Go Core Team в прошлом, либо активно работали над Go компилятором извне. Сам модуль используется внутри inet.af/netaddr который, в свою очередь, тянут в том числе и большие проекты.
Недостаток у go4.org/intern один: написан он с очень большим процентом черной магии, часть из которой еще и сильно ненадежна. Настолько ненадежна, что создателям модуля пришлось сделать (и регулярно обновлять) дополнительный модуль go4.org/unsafe/assume-no-moving-gc единственная цель которого, это убедиться, что сборщик мусора в Go все еще не двигает объекты в памяти хипа.
Проблема стала настолько явной, что Михаэль Кнызэк (один из ключевых разработчиков рантайма Go) предложил решить проблему уже на уровне стандартной библиотеки. Дескать не дело это, что модуль от которого зависит примерно 0,1% всей экосистемы (что достаточно много), может работать только в текущей внутрянке Go. Да и на дженерики бы уже неплохо все перенести. Предложенное API достаточно простое: есть одна глобальная функция которая возвращает враппер вокруг переменной и гарантирует ее уникальность в памяти. Враппер же нужен для быстрого сравнения уникальных значений между собой. А вся магия будет скрыта внутри райнтайма, который самостоятельно будет удалять переменные на которых больше никто не ссылается.
На мой взгляд, это попытка в очередной раз отложить внедрение слабых ссылок, потребность в которых назрела и перезрела уже давно. Однако меня устроит и такой вариант развития событий, ибо уже лучше чем ничего или магия которая может в любой момент развалиться.
Практически все разработчики сталкиваются с проблемой уникальности данных на уровне приложения. Чаще всего это вопрос удаления повтора строк, т.к. именно этот тип данных является самым «ходовым» в случае работы с хранилищами. А где хранилища, там и кеши и вопрос о затратах памяти. И рано или поздно, в любой достаточно сложной системе кеширования встает вопрос дедупликации - хранить повторяющиеся строки уж очень дорого на больших обьемах данных.
Неофиты спросят: «а в чем проблема? Почему нельзя использовать обычный словарь под мьютексом?». И ведь правда, мы можем использовать тип
map
для хранения уникальных значений любых сравниваемых типов. По скорости, словарь из стандартной библиотеки, превзойдут только уж совсем специализированные словари, которые большинство писать никогда не будет. Однако у этого подхода есть один существенный, но критический вопрос: как удалять ключи которых больше нет в нашей системе?В языках со сборщиком мусора, типо Java и C#, для решения этой проблемы есть специализированные типы (
WeakHashMap
, WeakSet
) которые автоматически удаляют ключи, на которые никто больше не ссылается. Под капотом практически все они используют weak reference (слабая ссылка, если только она ссылается на переменную, то сборщик мусора имеет право собрать переменную). Однако разработчики компилятора Go активно сопротивляются внедрению слабых ссылок в язык. Причины тому разные, но основная мысль кроется в нежелании усложнять рантайм и сборщик мусора без «лишней» необходимости.Однако если чему-то сопротивляться, это не значит, что в этом чем-то пропадет потребность. Модуль go4.org/intern содержит в себе реализацию такой системы дедупликации значений. Авторами этого пакета являются разработчики Tailscale, часть из которых либо являлись частью Go Core Team в прошлом, либо активно работали над Go компилятором извне. Сам модуль используется внутри inet.af/netaddr который, в свою очередь, тянут в том числе и большие проекты.
Недостаток у go4.org/intern один: написан он с очень большим процентом черной магии, часть из которой еще и сильно ненадежна. Настолько ненадежна, что создателям модуля пришлось сделать (и регулярно обновлять) дополнительный модуль go4.org/unsafe/assume-no-moving-gc единственная цель которого, это убедиться, что сборщик мусора в Go все еще не двигает объекты в памяти хипа.
Проблема стала настолько явной, что Михаэль Кнызэк (один из ключевых разработчиков рантайма Go) предложил решить проблему уже на уровне стандартной библиотеки. Дескать не дело это, что модуль от которого зависит примерно 0,1% всей экосистемы (что достаточно много), может работать только в текущей внутрянке Go. Да и на дженерики бы уже неплохо все перенести. Предложенное API достаточно простое: есть одна глобальная функция которая возвращает враппер вокруг переменной и гарантирует ее уникальность в памяти. Враппер же нужен для быстрого сравнения уникальных значений между собой. А вся магия будет скрыта внутри райнтайма, который самостоятельно будет удалять переменные на которых больше никто не ссылается.
На мой взгляд, это попытка в очередной раз отложить внедрение слабых ссылок, потребность в которых назрела и перезрела уже давно. Однако меня устроит и такой вариант развития событий, ибо уже лучше чем ничего или магия которая может в любой момент развалиться.
GitHub
unique: new package with unique.Handle · Issue #62483 · golang/go
Proposal: unique package Updated: 10 April 2024 Oct 4th EDIT: Changed package name from "intern" to "unique" and renamed "Symbol" to "Handle" based on feedba...
Go Update
Update: proposal: spec: add untyped builtin zero Собрав фидбек Расс предлагает немного изменить правила использования для zero: новый идентификатор можно будет использовать для присваивания и сравнения только там где недоступны другие «короткие» идентификаторы…
proposal: spec: add untyped builtin zero (closed)
Случилось неожиданное. Предложение было принято. А затем собрав фидбэк (среди которого высказался и Роб «наше все» Пайк) Расс принял решение отозвать предложенное изменение. И хотя с самим отзывом я в корне не согласен, я могу понять причины: «срач» в ветке не утихал ни на день, породил два контр-предложения и вызывал новые проблемы в объяснении Go механик новичкам.
Однако сам факт отзыва расстроил меня под двум причинам:
- После принятия предложения и нескольких страниц срача, Расс обьявил, что в отсутствии новой информации, решение о принятии изменено не будет. А затем спустя несколько дней, в течении которых срач все равно продолжился, предложение было отозвано без каких либо комментариев. Что подводит к неприятной мысли о том, что любое предложение можно заставить отозвать просто через продолжение спора в обсуждении.
- Go Core Team явно имело внутренние разговоры по этому вопросу, однако поделится ими они не посчитали нужным. На мой взгляд, сие идет против духа открытого ПО. Но так как по факту Go полностью владеет Google, то и Open Source у нас очень условный.
Итог: на одно изменение меньше в Go 1.22. Возможно это и к лучшему…
Случилось неожиданное. Предложение было принято. А затем собрав фидбэк (среди которого высказался и Роб «наше все» Пайк) Расс принял решение отозвать предложенное изменение. И хотя с самим отзывом я в корне не согласен, я могу понять причины: «срач» в ветке не утихал ни на день, породил два контр-предложения и вызывал новые проблемы в объяснении Go механик новичкам.
Однако сам факт отзыва расстроил меня под двум причинам:
- После принятия предложения и нескольких страниц срача, Расс обьявил, что в отсутствии новой информации, решение о принятии изменено не будет. А затем спустя несколько дней, в течении которых срач все равно продолжился, предложение было отозвано без каких либо комментариев. Что подводит к неприятной мысли о том, что любое предложение можно заставить отозвать просто через продолжение спора в обсуждении.
- Go Core Team явно имело внутренние разговоры по этому вопросу, однако поделится ими они не посчитали нужным. На мой взгляд, сие идет против духа открытого ПО. Но так как по факту Go полностью владеет Google, то и Open Source у нас очень условный.
Итог: на одно изменение меньше в Go 1.22. Возможно это и к лучшему…
✅ И немного позитива: sync: add Map.Clear method
Там верно заметили, что раз у нас теперь есть встроенная функция
Там верно заметили, что раз у нас теперь есть встроенная функция
clear
для очистки словарей и слайсов, то хорошо бы такое иметь для sync.Map
. Разработчики Go согласились и предложение было принято без лишних слов. Ждем реализации в Go 1.22.GitHub
sync: add Map.Clear method · Issue #61696 · golang/go
Since we have landed #56351 for clear builtin map, but we seems forget the sync variant sync.Map, let's do it!
📝 Где посмотреть список изменений в будущем релизе.
Список изменений на следующий релиз всегда доступен на https://tip.golang.org
Для Go 1.21 это был https://tip.golang.org/doc/go1.21
Для Go 1.22 это есть https://tip.golang.org/doc/go1.22
Для Go 1.23 это будет https://tip.golang.org/doc/go1.23
Однако сама страничка появляется примерно на второй-третий месяц разработки версии, а настоящая актуализация данных начинается за месяц-два до самого релиза. Т.е. сейчас на страничке 1.22 еще многого нет из того, что точно попадет в релиз.
Список изменений на следующий релиз всегда доступен на https://tip.golang.org
Для Go 1.21 это был https://tip.golang.org/doc/go1.21
Для Go 1.22 это есть https://tip.golang.org/doc/go1.22
Для Go 1.23 это будет https://tip.golang.org/doc/go1.23
Однако сама страничка появляется примерно на второй-третий месяц разработки версии, а настоящая актуализация данных начинается за месяц-два до самого релиза. Т.е. сейчас на страничке 1.22 еще многого нет из того, что точно попадет в релиз.
tip.golang.org
The Go Programming Language
Go is an open source programming language that makes it simple to build secure, scalable systems.
HTML Embed Code: