Предопределенный идентификатор zero - универсальное нулевое значение для возврата и сравнений.
Тем времени поезд нововведений от Расса и не думает останавливаться. Вообще это предложение уже высказывалось много раз, но только после прихода дженериков стало понятно, отрицать необходимость подобного больше возможности нет.
Из главного:
- Появлется новый предопределенный идентификатор
- Переменные любого типа поддерживают сравнение с
- Переменным имеющим тип всегда можно присвоить
- Из функций и методов можно возвращать данные с использованием новой конструкции. Например вот так
- Сравнение с
Фактически
Из главных мотиваторов нового предложения по улучшению языка Кокс выделел две вещи:
- Ему надоело объяснять зачем нужна конструкция
- Вопрос сравнения с нулевым значением внутри дженерик функций встал особенно остро после принятия
На вопрос почему не использовать
От себя добавлю - как и в случае с min/max ситуация назрела и перезрела. Особенно остро это ощущается на бизнес логике, где люди что бы не писать
Скоро и в вашем коде…
Тем времени поезд нововведений от Расса и не думает останавливаться. Вообще это предложение уже высказывалось много раз, но только после прихода дженериков стало понятно, отрицать необходимость подобного больше возможности нет.
Из главного:
- Появлется новый предопределенный идентификатор
zero. В отличии от ключевого слова (типо type) он может быть переопределен в контексте поэтому ваш старый код который использует zero как переменную или метод, продолжит работать и дальше.- Переменные любого типа поддерживают сравнение с
zero.- Переменным имеющим тип всегда можно присвоить
zero. Будут работать конструкции var my Struct = zero или myInt := int(zero) но вот i := zero работать не будет.- Из функций и методов можно возвращать данные с использованием новой конструкции. Например вот так
return zero, zero, err- Сравнение с
zero доступно внутри дженерик функций у которых на типы-параметры стоит констрейнт any. В данный момент это очень большая головная боль для тех кто пишет библиотеки со структурами данных.Фактически
zero это аналог nil только покрывающий вообще все типы.Из главных мотиваторов нового предложения по улучшению языка Кокс выделел две вещи:
- Ему надоело объяснять зачем нужна конструкция
*new(T) и он уверен что мы можем лучше.- Вопрос сравнения с нулевым значением внутри дженерик функций встал особенно остро после принятия
cmp.Or о котором я обязательно расскажу в других сообщениях.На вопрос почему не использовать
_ Рас ответил, что if myVal == _ { … } выглядит неидиоматично. А вот на вопрос почему не расширить nil ответ посложнее - многие потенциальные баги были пойманы на этапе компиляции за счет того, что nil работает только с map/slice/chan/interface/pointer и эту семантику хотелось бы сохранить и в будущем. Из реального примера, Расс приводит ситуацию когда человек написал if(someValue) вместо if(*someValue) в Сишном коде, что привело к значительно потере данных внутри Google (решилось через резервные системы).От себя добавлю - как и в случае с min/max ситуация назрела и перезрела. Особенно остро это ощущается на бизнес логике, где люди что бы не писать
return MySomeRandomStruct{}, err использовали указатели и не понимали к каким следствиям это может привести.func checkForZero(potentialZero MyType) (SomeType, error) {
if val == zero {
return zero, errors.New("is zero")
}
return SomeType(val), zero
}Скоро и в вашем коде…
GitHub
spec: add untyped builtin zero · Issue #61372 · golang/go
I propose to add a new predeclared identifier zero that is an untyped zero value. While nil is an untyped zero value restricted to chan/func/interface/map/slice/pointer types, zero would be an unty...
🔥24👍11❤2
По горячим следам:
- Зачем нужна конструция *new(T)?
В дженерик функциях существует только два способа вернуть нулевое значение типа-параметра. Первый это
- Почему нельзя просто обьявить IsEmpty(val) и CreateEmpty()?
Это будет новое встроенное определение которое покрывает лишь половину кейсов. Go славится своей попыткой снизить когнитивную нагрузку, поэтому отдельные конструкции для сравнения с нулем и создания нуля будут выглядеть как переусложение.
Задавайте ваши вопросы в комментариях, будем дополнять список.
- Зачем нужна конструция *new(T)?
В дженерик функциях существует только два способа вернуть нулевое значение типа-параметра. Первый это
var zeroVal T; return zeroVal - две строчки после форматирования. Либо вот *new(T) - в одну.- Почему нельзя просто обьявить IsEmpty(val) и CreateEmpty()?
Это будет новое встроенное определение которое покрывает лишь половину кейсов. Go славится своей попыткой снизить когнитивную нагрузку, поэтому отдельные конструкции для сравнения с нулем и создания нуля будут выглядеть как переусложение.
Задавайте ваши вопросы в комментариях, будем дополнять список.
🔥9👍5👏1
Корутины в Go
Пока идет бурное обсуждение по поводу
Вообще роль корутин (т.е. сопрограмм) в Go с самого момента появления языка выполняли горутины - почти все изучая Go пишут что-то вроде
В общей терминологии это звучит так:
- Горутины нужны тогда, когда нужно асинхронное, параллельное исполнение. Две горутины могут исполнятся одновременно, независимо, им не нужно явно принимать и отдавать управление. Управлением горутинами, в общем случае, занимается рантайм.
- Корутины нужны тогда, когда нужно асинхронное, последовательное исполнение. Только одна корутина исполняется в момент времени, отдавая и принимая обратно управление в специальных точках-функциях (yield). Вызывающий код сам решает, в какой момент времени происходит переключение между корутинами.
Используя каналы с горутинами можно получить частичное поведение корутин — горутину можно заблокировать отправив данные другой горутине через канал и ожидая от нее ответ по второму каналу. Более того, полную подобную реализацию корутин Расс приводит в статье, показывая, что их можно реализовать как библиотечные функции и без новых языковых конструкций. Полная версия кода показывает вариант с ранним выходом и передачей паник вызывающей стороне.
Однако у всего это кода есть один существенный минус - скорость его исполнения. На MacBook Pro 2019 года один вызов
От себя добавлю, что вопрос использования каналов как инструмента общения последовательных потоков управления поднимался несколько раз - тот же генератор, сигнатура которого приведена сверху, не требует, в своей сути, параллельного исполнения: большая часть времени тратится на синхронизацию данных между двумя горутинами через канал. Однако вариант однопоточных каналов авторы языка не стали рассматривать, т.к. в таком случае появлялась бы еще одна синтаксическая конструкция, которая нужна в достаточно небольшом числе сценариев (по отношению к общему), а вот случаи ее неправильного использования приведут к трудноуловимым гонкам данных.
Я рекомендую посмотреть код в самой статье, даже если вы плохо знаете английский - это хорошая гимнастика для мозгов с использованием каналов как двунаправленного средства обмена данными.
Пока идет бурное обсуждение по поводу
zero, Расс Кокс продолжает свои рассуждения о хранении данных внутри горутины-потока исполнения. В этот раз он рассматривает корутины, как вариант генераторов/итераторов.Вообще роль корутин (т.е. сопрограмм) в Go с самого момента появления языка выполняли горутины - почти все изучая Go пишут что-то вроде
func generate(num int) <-chan int { ... } для генерации списка чисел. Однако Расс утверждает, что в языке есть место и для корутин. В общей терминологии это звучит так:
- Горутины нужны тогда, когда нужно асинхронное, параллельное исполнение. Две горутины могут исполнятся одновременно, независимо, им не нужно явно принимать и отдавать управление. Управлением горутинами, в общем случае, занимается рантайм.
- Корутины нужны тогда, когда нужно асинхронное, последовательное исполнение. Только одна корутина исполняется в момент времени, отдавая и принимая обратно управление в специальных точках-функциях (yield). Вызывающий код сам решает, в какой момент времени происходит переключение между корутинами.
Используя каналы с горутинами можно получить частичное поведение корутин — горутину можно заблокировать отправив данные другой горутине через канал и ожидая от нее ответ по второму каналу. Более того, полную подобную реализацию корутин Расс приводит в статье, показывая, что их можно реализовать как библиотечные функции и без новых языковых конструкций. Полная версия кода показывает вариант с ранним выходом и передачей паник вызывающей стороне.
Однако у всего это кода есть один существенный минус - скорость его исполнения. На MacBook Pro 2019 года один вызов
yield занимает порядка 380ns, что очень долго если говорить про итерацию по коллекциям или относительно простые арифметические операции. Однако имея доступ к внутренностям рантайма и подправив несколько мест в нем (бонусы бытия техлидом Go 😄) специально для этого случая, Рассу удалось достигнуть затрат в 40ns на одну итерацию, что в 10 раз быстрее изначальной реализации и уже достаточно быстро для использования подобного паттерна в общем случае.От себя добавлю, что вопрос использования каналов как инструмента общения последовательных потоков управления поднимался несколько раз - тот же генератор, сигнатура которого приведена сверху, не требует, в своей сути, параллельного исполнения: большая часть времени тратится на синхронизацию данных между двумя горутинами через канал. Однако вариант однопоточных каналов авторы языка не стали рассматривать, т.к. в таком случае появлялась бы еще одна синтаксическая конструкция, которая нужна в достаточно небольшом числе сценариев (по отношению к общему), а вот случаи ее неправильного использования приведут к трудноуловимым гонкам данных.
Я рекомендую посмотреть код в самой статье, даже если вы плохо знаете английский - это хорошая гимнастика для мозгов с использованием каналов как двунаправленного средства обмена данными.
👍34🔥4✍3
proposal 61405: spec: add range over int, range over func
Вот и настал тот момент - Расс официально предлагает добавить поддержку
▸ Range over integer:
▸ Range over function: теперь можно будет писать код
Значения которые не нужны запрашивающему коду (тот кто вызывает
Возвращаемое
Детали реализации и различные тонкости (такие как, что будет если
Вот и настал тот момент - Расс официально предлагает добавить поддержку
range над следующими видами выражений:▸ Range over integer:
for x := range n { ... } где n целочисленное выражение или переменная. Будет эквивалентно for x := 0; x < n; x++ { ... }▸ Range over function: теперь можно будет писать код
for x, y := range f { … } где f это функция или метод со следующей сигнатурой: 1. func(yield func(T1, T2)bool) bool
2. func(yield func(T1)bool) bool
3. func(yield func()bool) boolЗначения которые не нужны запрашивающему коду (тот кто вызывает
range) будут автоматически выброшены. Например для функции func(yield func(T1, T2) bool) bool допустимы следующие варианты range: 1. for x, y := range f { ... }
2. for x, _ := range f { ... }
3. for _, y := range f { ... }
4. for x := range f { ... }
5. for range f { ... }|Возвращаемое
yield булево значение позволяет определить вызываемому коду (тот кого вызывают через range), что пора прекратить исполнение и двигаться на выход (в случае break или return). Т.е. в случае for range f { break; } сразу после первого вызова yield вернет false.Детали реализации и различные тонкости (такие как, что будет если
yield будет вызван после выхода из тела range) пока обсуждаются.GitHub
spec: add range over int, range over func · Issue #61405 · golang/go
Following discussion on #56413, I propose to add two new types that a for-range statement can range over: integers and functions. In the spec, the table that begins the section would have a few mor...
👍17😐14👎2🔥1
И сразу ответы на вопросы:
▸ Почему такая странная сигнатура у f?
С приходом дженериков, необходимость итерации по кастомным структурам данных встала особенно остро - в особенности по тем, в которых невозможно или очень сложно зафиксировать текущее положение. В качестве примера - попробуйте придумать итератор который будет работать одновременно и для
▸ Почему нельзя сделать интерфейс?
На самом деле нет большой разницы между
и
▸ Как поиграться и попробовать на практике?
▸ Почему такая странная сигнатура у f?
С приходом дженериков, необходимость итерации по кастомным структурам данных встала особенно остро - в особенности по тем, в которых невозможно или очень сложно зафиксировать текущее положение. В качестве примера - попробуйте придумать итератор который будет работать одновременно и для
[]string и map[string]string. Затем попробуйте придумать как добавить поддержку древовидной структуры данных. А затем добавьте в микс каналы. Когда дойдете до import "reflect" можно смело останавливаться.▸ Почему нельзя сделать интерфейс?
На самом деле нет большой разницы между
func(yield func(T1, T2)bool) boolи
type Iterator interface { Iter(yield (V T, V2 T2) bool) bool }. Более того, вариант с интерфейсом обсуждали, но решили отказаться от него, т.к. это будет противоречить принципам языка, где методы у типов не являются обязательным условием для полноценности этого самого типа. Кому интересно, можете погрузиться в дискуссии про дженерики - там это хорошо прописано. Кроме того, в текущем предложении это вызывает проблемы с взаимодействием с типом type MyInt int у которого обьявлен метод Iter.▸ Как поиграться и попробовать на практике?
go install golang.org/dl/gotip@latest
gotip download 510541 # download and build CL 510541
gotip version # should say "(w/ rangefunc)"
gotip run foo.go👍14
proposal 61489: add built-in null for zero value of pointers - немножко странного в этот пятничный вечер.
Иэн Ланс Тейлор (один из ключевых разработчиков компилятора и языка Go) предлагает добавить предопределенный идентификатор
В дальнейшей части документа рассказывается про переход на новые правила и возможное введение запрета на присваивание
Иэн признает, что предложение скорее всего будет отклонено, но ему было важно записать эту идею, что-бы в будущем люди могли ссылаться на нее при обсуждении проблемы
Иэн Ланс Тейлор (один из ключевых разработчиков компилятора и языка Go) предлагает добавить предопределенный идентификатор
null в язык. И нет, это не первоапрельская шутка: новый идентификатор будет работать аналогично nil, но только для типов-указателей. Согласно задумке автора, это изменение поможет лучше понимать, что выражение err != nil не гарантирует отсутствие нулевого указателя на данные внутри переменной интерфейса.В дальнейшей части документа рассказывается про переход на новые правила и возможное введение запрета на присваивание
nil указателям в будущих версиях Go. Однако все остальные типы (slice/map/interface/chan) будут продолжать использовать nil.Иэн признает, что предложение скорее всего будет отклонено, но ему было важно записать эту идею, что-бы в будущем люди могли ссылаться на нее при обсуждении проблемы
typed nil и поиска решений для нее.GitHub
proposal: Go 2: add built-in null for zero value of pointers · Issue #61489 · golang/go
There is a long-standing confusion in Go between a nil interface value and a non-nil interface value that holds a pointer type with a value of nil. There is a FAQ entry for Why is my nil error valu...
💩4👎3
Дайджест предложений в которых участвует Go Core Team:
- ✅ spec: less error-prone loop variable scoping #60078 — изменение в механике «захвата» переменных внутри тела цикла. Минус один вопрос на интервью начиная с Go 1.22. О нем я все еще надеюсь написать отдельно.
- ✅ testing: add Name to track file and line of test case declaration #52751 — новая функция для тестов, который позволяет записывает где она была вызвана. Удобно для табличных тестов.
- ✅x/net/quic: add QUIC implementation #58547 — HTTP3 все ближе.
- ❌builtin: add abs to get absolute value of numbers( integer and float pointers) #60623 — если мы завезли min/max это не значит, что мы завезем и остальное.
- ❌testing: a less error-prone API for benchmark iteration #48768 — корректные бенчмарки писать сложно, но это предложение ситуацию лучше не делает.
- ⌛proposal: net/http: enhanced ServeMux routing #61410 — роутер как у гориллы, теперь в стадартной библиотеке.
Полный список - тут.
- ✅ spec: less error-prone loop variable scoping #60078 — изменение в механике «захвата» переменных внутри тела цикла. Минус один вопрос на интервью начиная с Go 1.22. О нем я все еще надеюсь написать отдельно.
- ✅ testing: add Name to track file and line of test case declaration #52751 — новая функция для тестов, который позволяет записывает где она была вызвана. Удобно для табличных тестов.
- ✅x/net/quic: add QUIC implementation #58547 — HTTP3 все ближе.
- ❌builtin: add abs to get absolute value of numbers( integer and float pointers) #60623 — если мы завезли min/max это не значит, что мы завезем и остальное.
- ❌testing: a less error-prone API for benchmark iteration #48768 — корректные бенчмарки писать сложно, но это предложение ситуацию лучше не делает.
- ⌛proposal: net/http: enhanced ServeMux routing #61410 — роутер как у гориллы, теперь в стадартной библиотеке.
Полный список - тут.
GitHub
spec: less error-prone loop variable scoping · Issue #60078 · golang/go
We propose to change for loop variables declared with := from one-instance-per-loop to one-instance-per-iteration. This change would apply only to packages in modules that explicitly declare a new ...
🔥8👍5
Go 1.22 inlining overhaul
А пятница и не думает заканчиваться — Мэттью Димпскай и Тэн Мкинтош (крутая фамилия) работают над полной переработкой оптимизации «встраивание тела функций» в компиляторе Go. Для тех кто не в курсе — встраивание тела функций, это когда компилятор вместо вставки кода вызова функции, вставляет весь код этой функции прямо туда, откуда она вызывается. Таким образом уходят затраты на ее вызов, что на небольших операциях (арифметика на массивах например) может быть очень заметно. Минусы встраивания — разрастание размера бинаря.
Сама оптимизация, наряду с эскейп анализом, была и остается одной из слабых мест компилятора Go — запрос на ее улучшение постоянно идет от разработчиков высоконагруженных приложений, но до недавнего времени разработчики языка не хотели усложнять отвечающий за нее код. Ситуацию поменял переход бэкенда компилятора на новую платформу — открылось больше возможностей для различных оптимизаций и делать их стало проще.
Сейачс разработчики хотят перейти от простой модели затрат, в которой возможность вставки функции определяется числом синтаксических элементов в ней, к комбинации эвристик посложнее. Например — надеются начать встраивать тело функций, которые вызываются только в одном месте. А при учете решения по встраиванию начнут брать в расчет факты о том, разблокирует ли это дальнейшие оптимизации.
Результаты и прирост производительности будут ближе к Go 1.22. Ждем.
А пятница и не думает заканчиваться — Мэттью Димпскай и Тэн Мкинтош (крутая фамилия) работают над полной переработкой оптимизации «встраивание тела функций» в компиляторе Go. Для тех кто не в курсе — встраивание тела функций, это когда компилятор вместо вставки кода вызова функции, вставляет весь код этой функции прямо туда, откуда она вызывается. Таким образом уходят затраты на ее вызов, что на небольших операциях (арифметика на массивах например) может быть очень заметно. Минусы встраивания — разрастание размера бинаря.
Сама оптимизация, наряду с эскейп анализом, была и остается одной из слабых мест компилятора Go — запрос на ее улучшение постоянно идет от разработчиков высоконагруженных приложений, но до недавнего времени разработчики языка не хотели усложнять отвечающий за нее код. Ситуацию поменял переход бэкенда компилятора на новую платформу — открылось больше возможностей для различных оптимизаций и делать их стало проще.
Сейачс разработчики хотят перейти от простой модели затрат, в которой возможность вставки функции определяется числом синтаксических элементов в ней, к комбинации эвристик посложнее. Например — надеются начать встраивать тело функций, которые вызываются только в одном месте. А при учете решения по встраиванию начнут брать в расчет факты о том, разблокирует ли это дальнейшие оптимизации.
Результаты и прирост производительности будут ближе к Go 1.22. Ждем.
Google Docs
Go 1.22 inlining overhaul
Go 1.22 inlining overhaul , with contributions from , , , and Last update: The Go compiler’s inliner has never been particularly good. It wasn’t until Go 1.12, released in 2019, that the Go compiler supported inlining more than leaf functions, and we’ve…
👍26🔥3
Generic Null[T] in sql package
Я часто слышу фразу: «Ну вот у нас есть дженерики, а зачем они конкретно мне?». Действительно, большинство использований дженериков приходиться на библиотечный код, и для разработчика бизнес логики их использование чаще всего довольно прозрачно. Чаще всего настолько прозрачно, что они скорее всего не увидят характерных квадратных скобок вне привычной сигнатуры словаря
Однако есть и полезные исключения типов и функций где тайп параметры все таки видно. В 1.19 нам завезли первый дженерик тип в пакет
В 1.22 нас ждет еще одно полезное для всех нововведение: тип
А какие у вас есть семейства типов и функций которые могли бы получить реализацию в дженериках и облегчить вам жизнь? Пишите в комментариях.
Я часто слышу фразу: «Ну вот у нас есть дженерики, а зачем они конкретно мне?». Действительно, большинство использований дженериков приходиться на библиотечный код, и для разработчика бизнес логики их использование чаще всего довольно прозрачно. Чаще всего настолько прозрачно, что они скорее всего не увидят характерных квадратных скобок вне привычной сигнатуры словаря
map, либо увидят их по минимуму. Те-же новые функции из пакетов slices/maps большинство будут использовать в вариантах похожих на println("First negative at index", slices.IndexFunc([]int{0, 42, -10, 8}, func(n int) bool { return n < 0 })) где тайп параметры не видны вызывающему.
Однако есть и полезные исключения типов и функций где тайп параметры все таки видно. В 1.19 нам завезли первый дженерик тип в пакет
sync/atomic: atomic.Pointer[T] который полностью решил все задачи, которые раньше решал требующий тайп ассертов atomic.Value. Больше нет необходимости приводить тип вручную, или получить панику забыв это сделать при очередном рефакторинге. Да и памяти atomic.Pointer[T] ест в два раза меньше (8 байт вместо 16). Вопрос в комментарии: однако есть один cценарий который все еще лучше покрывается через atomic.Value. Что это за сценарий?В 1.22 нас ждет еще одно полезное для всех нововведение: тип
sql.Null[T] который обьединит собой не только типы sql.NullString или sql.NullFloat64, но еще и покроет ваши кастомные типы. Теперь работа со стандартными типами и со своими не будет отличаться, что даст еще один плюс к общей читаемости кода (единообразие тоже часть читаемости кода). Самое прекрасное, что полная реализация sql.Null[T] умещается в 22 строчки и которую легко поймет любой Go разработчик, даже тот который никогда не сталкивался с дженериками.А какие у вас есть семейства типов и функций которые могли бы получить реализацию в дженериках и облегчить вам жизнь? Пишите в комментариях.
GitHub
database/sql: add generic Null[T] · Issue #60370 · golang/go
database/sql doesn't have NullUInt64. So drivers and ORMs may implement their own NullUInt64. Application developers would be confused which NullUInt64 is returned by dynamic Scan methods. When...
🔥21👍5❤2
Update: proposal: spec: add untyped builtin zero
Собрав фидбек Расс предлагает немного изменить правила использования для
Никаких сложных выборов - писать
Собрав фидбек Расс предлагает немного изменить правила использования для
zero: новый идентификатор можно будет использовать для присваивания и сравнения только там где недоступны другие «короткие» идентификаторы — nil, "", 0. В число этих случаев входят дженерики с констрейнтом any.Никаких сложных выборов - писать
return "" или return zero.GitHub
spec: add untyped builtin zero · Issue #61372 · golang/go
I propose to add a new predeclared identifier zero that is an untyped zero value. While nil is an untyped zero value restricted to chan/func/interface/map/slice/pointer types, zero would be an unty...
👍7😐4
Опросы в канале, да или нет?
Там ко мне пришлис рекламой с предложением разместить опрос. Я обычно никакие опросы никогда сам не прохожу (кроме Go Developer Survey), поэтому оставляю решение за аудиторией. Как проголосуете, так и будем делать.
П.С. Рекламы не будет. Точно. Не сейчас, не потом.
Там ко мне пришли
П.С. Рекламы не будет. Точно. Не сейчас, не потом.
👍15👎2
Опрос
Тут это, ребята из DevCrowd проводят исследование среди Go-разработчиков:
- Какие навыки для go-разработчиков самые важные
- Какие инструменты используются в работе
- Как попадают в профессию и куда из нее уходят
- Полезные для развития каналы, курсы и книги
Предлогаю пройти опрос, рассказать про ваш опыт и помочь сделать исследование максимально охватным. Его результаты будут в открытом доступе, и помогут нам всем сравнить свои ожидания от коллег по Go с рыночными, построить план, что нужно изучить, и просто понять, что происходит с индустрией!
Пройти опрос можно тут.
Тут это, ребята из DevCrowd проводят исследование среди Go-разработчиков:
- Какие навыки для go-разработчиков самые важные
- Какие инструменты используются в работе
- Как попадают в профессию и куда из нее уходят
- Полезные для развития каналы, курсы и книги
Предлогаю пройти опрос, рассказать про ваш опыт и помочь сделать исследование максимально охватным. Его результаты будут в открытом доступе, и помогут нам всем сравнить свои ожидания от коллег по Go с рыночными, построить план, что нужно изучить, и просто понять, что происходит с индустрией!
Пройти опрос можно тут.
survey.alchemer.eu
Исследование рынка Go-разработчиков, 2023
Исследование рынка Go-разработчиков, 2023.
👍9👎2
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...
🔥28
Дайджест активных предложений и дискуссий 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 - универсальное нулевое значение для возврата и сравнений.
Тем времени поезд нововведений от Расса и не думает останавливаться. Вообще это предложение уже высказывалось много раз, но только после прихода дженериков стало…
Тем времени поезд нововведений от Расса и не думает останавливаться. Вообще это предложение уже высказывалось много раз, но только после прихода дженериков стало…
👍10🔥8❤3
Релиз 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
👍58🔥10
И снова про итераторы…
Если прошлое предложение от Расса показывало как будут выглядеть итераторы, то новое предложение показывает как мы будем ими пользоваться и готовит для этого огромный фундамент.
✅ У нас появятся новый пакет
✅ У нас будет четкий стандарт именования функций которые возвращают итераторы.
❗ Если итерация может провалится, правильным и идиоматичным типом итератора будет
❗ Нам дадут функцию для преобразования наших 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...
🔥17❤1
Персональная запись: сегодня мне исполнился 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…
🔥76👏12👍10❤9
📝 Изменение формата имени версий 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 скрипты.
👍20❤1