Map на новом слайсе пишется за минуту — все его видели:func Map[T, U any](slice []T, fn func(T) U) []U {
result := make([]U, len(slice))
for i, v := range slice {
result[i] = fn(v)
}
return result
}Работает. Просто. Но всегда выделяет новый слайс, даже если результат сразу пойдёт в следующую трансформацию.
Как использовать iter.Seq
С Go 1.23
Map можно написать иначе — возвращать не слайс, а итератор:func Map[A, B any](seq iter.Seq[A], f func(A) B) iter.Seq[B] {
return func(yield func(B) bool) {
for v := range seq {
if !yield(f(v)) {
return
}
}
}
}Функция возвращает замыкание, которое будет вызываться по требованию.
Пример:
numbers := slices.Values([]int{1, 2, 3, 4, 5})
result := slices.Collect(
Map(
Map(numbers, func(n int) int { return n * 2 }),
func(n int) int { return n + 10 },
),
)
// [12, 14, 16, 18, 20]Два
Map подряд — один проход по данным, одна аллокация на Collect. Промежуточного слайса нет.Нюансы
iter.Seq, slices.Values и slices.Collect — всё это Go 1.23+.Fluent-чейнинга
seq.Map(f).Map(g) не будет — в Go нельзя навесить дженерик-метод на произвольный тип. Живём с вложенными вызовами.📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoToProduction