- Итераторы: iter и slices
- Новый пакет unique
- Улучшение таймеров
- Телеметрия в Go 1.23
- Поддержка новых платформ
Итераторы: iter и slices
Введены итераторы для работы с пользовательскими последовательностями данных. Появился новый пакет iter
, а также функции для работы с итераторами в пакетах slices
и maps
. Теперь можно, например, обрабатывать ключи карты с помощью итераторов.
Пример использования итераторов:
package main
import (
"fmt"
"golang.org/x/exp/maps"
"golang.org/x/exp/slices"
)
func main() {
// Создаём карту
m := map[string]int{
"apple": 5,
"banana": 2,
"cherry": 7,
}
// Получаем все ключи карты через итератор
keys := maps.Keys(m)
// Сортируем ключи
sortedKeys := slices.Sorted(keys)
// Выводим отсортированные ключи
fmt.Println(sortedKeys) // [apple banana cherry]
}
Этот код демонстрирует основные функции нового пакета iter
, который используется для работы с коллекциями данных, например, картами и срезами.
Новый пакет unique
Позволяет "канонизировать" значения, создавая одну общую копию для одинаковых объектов, что помогает сократить использование памяти.
Пример использования пакета unique в Go 1.23:
package main
import (
"fmt"
"golang.org/x/exp/unique"
)
func main() {
// Создаем объект для канонизации строк
u := unique.Make[string]()
// Канонизируем несколько строк
handle1 := u.Handle("apple")
handle2 := u.Handle("banana")
handle3 := u.Handle("apple")
// Сравниваем канонизированные строки
fmt.Println(handle1 == handle3) // true
fmt.Println(handle1 == handle2) // false
// Выводим оригинальные значения
fmt.Println(handle1.Value()) // "apple"
fmt.Println(handle2.Value()) // "banana"
}
Это полезно в ситуациях, когда одно и то же значение используется многократно, и важно минимизировать избыточное потребление памяти.
Улучшение таймеров
Изменена реализация time.Timer и time.Ticker, что должно улучшить производительность. Тут с точки зрения интерфейса нового ничего нет, но под капотом разработчики гошки значительно увеличили скорость.
package main
import (
"fmt"
"time"
)
func main() {
// Создаем тикер, который срабатывает каждые 500 миллисекунд
ticker := time.NewTicker(500 * time.Millisecond)
// Запускаем цикл для обработки событий тикера
go func() {
for t := range ticker.C {
fmt.Println("Тик в:", t)
}
}()
// Останавливаем тикер через 2 секунды
time.Sleep(2 * time.Second)
ticker.Stop()
fmt.Println("Тикер остановлен")
}
Телеметрия в Go 1.23
А вот это уже действительно интересно. Добавлена телеметрия - теперь можно добровольно отправлять анонимные данные об использовании инструментов Go. Вот пример интеграции с OpenTelemetry и Jaeger:
package main
import (
"context"
"log"
"time"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
"go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
)
func initTracer() func() {
exporter, err := otlptracehttp.New(context.Background(),
otlptracehttp.WithEndpoint("your-apm-server:8200"),
otlptracehttp.WithInsecure(),
)
if err != nil {
log.Fatal(err)
}
tp := trace.NewTracerProvider(
trace.WithBatcher(exporter),
trace.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String("my-service"),
)),
)
otel.SetTracerProvider(tp)
return func() {
if err := tp.Shutdown(context.Background()); err != nil {
log.Fatal(err)
}
}
}
func main() {
cleanup := initTracer()
defer cleanup()
tracer := otel.Tracer("example-tracer")
ctx, span := tracer.Start(context.Background(), "example-operation")
time.Sleep(1 * time.Second)
span.End()
log.Println("Телеметрия отправлена в APM")
}
Поддержка новых платформ
Добавлена экспериментальная поддержка OpenBSD на RISC-V 64-bit.
Спасибо за прочтение! Не забудьте подписаться на мой телеграмм канал, где вы найдете больше полезной информации о разработке: @asanov_tech{:target="_blank" rel="nofollow"}