Как в Go выполняется сортировка? Расскажите про сортировку пользовательских типов данных.

Ответ

В Go идиоматический способ сортировки — использование пакета sort. Он предоставляет эффективные и гибкие инструменты для работы с любыми типами данных.

В основе пакета лежит интерфейс sort.Interface:


_type Interface interface {
    Len() int
    Less(i, j int) bool
    Swap(i, j int)
}
_```
Любой тип, реализующий этот интерфейс, может быть отсортирован функцией `sort.Sort()`.

### Способы сортировки пользовательских типов:

**1. Реализация `sort.Interface` (классический способ)**

Нужно определить три метода для вашего типа-слайса. Это полезно, когда сортировка является основным поведением для типа.

```go
_type User struct {
    Name string
    Age  int
}

// ByAge реализует sort.Interface для []User по полю Age
_type ByAge []User

func (a ByAge) Len() int           { return len(a) }
func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }

func main() {
    users := []User{
        {"Alice", 25},
        {"Bob", 20},
    }
    sort.Sort(ByAge(users))
    fmt.Println(users) // [{Bob 20} {Alice 25}]
}
_```

**2. Использование `sort.Slice` (современный и более гибкий способ)**

Эта функция, появившаяся в Go 1.8, не требует реализации интерфейса. Она принимает слайс и функцию `less` в качестве аргументов. Это удобнее для одноразовых или динамических сортировок.

```go
_func main() {
    users := []User{
        {"Alice", 25},
        {"Bob", 20},
    }

    // Сортировка по имени
    sort.Slice(users, func(i, j int) bool {
        return users[i].Name < users[j].Name
    })
    fmt.Println(users) // [{Alice 25} {Bob 20}]
}
_```

### Алгоритм и готовые функции

- **Алгоритм**: Стандартная библиотека Go использует **pdqsort** (Pattern-Defeating Quicksort), который является гибридом быстрой сортировки, пирамидальной сортировки и сортировки вставками. Он показывает отличную производительность в большинстве случаев.
- **Готовые функции**: Для базовых типов существуют удобные обертки, такие как `sort.Ints()`, `sort.Float64s()` и `sort.Strings()`, которые используют те же эффективные алгоритмы.