接口

1
2
3
4
5
6
// 如果 Less 方法返回 true,则会执行 Swap 方法。
type Interface interface {
Len() int // Len方法返回集合中的元素个数
Less(i, j int) bool // i>j,该方法返回索引i的元素是否比索引j的元素小、
Swap(i, j int) // 交换i, j的值
}

结构体

1
2
3
type IntSlice struct
type Float64Slice
type StringSlice

函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func Ints(a []int)
func IntsAreSorted(a []int) bool
func SearchInts(a []int, x int) int
func Float64s(a []float64)
func Float64sAreSorted(a []float64) bool
func SearchFloat64s(a []float64, x float64) int
func SearchFloat64s(a []flaot64, x float64) bool
func Strings(a []string)
func StringsAreSorted(a []string) bool
func SearchStrings(a []string, x string) int
func Sort(data Interface)
func Stable(data Interface)
func Reverse(data Interface) Interface
func ISSorted(data Interface) bool
func Search(n int, f func(int) bool) int

demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package main

import (
"fmt"
"sort"
)

type NewInts []uint

func (n NewInts) Len() int {
return len(n)
}

func (n NewInts) Less(i, j int) bool {
fmt.Println(i, j, n[i] < n[j], n)
return n[i] < n[j]
}

func (n NewInts) Swap(i, j int) {
n[i], n[j] = n[j], n[i]
}

func main() {
n := []uint{1,3,2}
sort.Sort(NewInts(n))
fmt.Println(n)
}

/*
输出:
1 0 false [1 3 2]
2 1 true [1 3 2]
1 0 false [1 2 3]
[1 2 3]
*/
1
2
3
4
5
6
7
// sort_int_slice_with_sugar
func main() {
sl := []int{89, 14, 8, 9, 17, 56, 95, 3}
fmt.Println(sl) // [89 14 8 9 17 56 95 3]
sort.Ints(sl)
fmt.Println(sl) // [3 8 9 14 17 56 89 95]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
type Lang struct {
Name string
Rank int
}

func main() {
langs := []Lang{
{"rust", 2},
{"go", 1},
{"swift", 3},
}
sort.Slice(langs, func(i, j int) bool { return langs[i].Rank < langs[j].Rank })
fmt.Printf("%v\n", langs) // [{go 1} {rust 2} {swift 3}]
}

引入泛型后的切片排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

import (
"fmt"
"sort"
)

type Ordered interface {
type int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr, float32, float64, string
}

type orderedSlice[T Ordered] []T

func (s orderedSlice[T]) Len() int { return len(s) }
func (s orderedSlice[T]) Less(i, j int) bool { return s[i] < s[j] }
func (s orderedSlice[T]) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

func OrderedSlice[T Ordered](s []T) {
sort.Sort(orderedSlice[T](s))
}

func main() {
s1 := []int32{3, 5, 2}
fmt.Println(s1) // [3 5 2]
OrderedSlice(s1)
fmt.Println(s1) // [2 3 5]

s2 := []string{"jim", "amy", "tom"}
fmt.Println(s2) // [jim amy tom]
OrderedSlice(s2)
fmt.Println(s2) // [amy jim tom]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import (
"fmt"
"sort"
)

type Lang struct {
Name string
Rank int
}

type sliceFn[T any] struct {
s []T
cmp func(T, T) bool
}

func (s sliceFn[T]) Len() int { return len(s.s) }
func (s sliceFn[T]) Less(i, j int) bool { return s.cmp(s.s[i], s.s[j]) }
func (s sliceFn[T]) Swap(i, j int) { s.s[i], s.s[j] = s.s[j], s.s[i] }

func SliceFn[T any](s []T, cmp func(T, T) bool) {
sort.Sort(sliceFn[T]{s, cmp})
}

func main() {
langs := []Lang{
{"rust", 2},
{"go", 1},
{"swift", 3},
}

SliceFn(langs, func(p1, p2 Lang) bool { return p1.Rank < p2.Rank })
fmt.Println(langs) // [{go 1} {rust 2} {swift 3}]
}

使用泛型方案, 由于少了到 interface{} 的装箱和拆箱操作,理论上 SliceFn 的性能要好于 sort.Slice 函数。