Golang slices.Sort
最后修改于 2025 年 4 月 20 日
本教程解释了如何在 Go 中使用 slices.Sort
函数。我们将通过不同数据类型的实际示例涵盖排序操作。
slices.Sort
函数按升序对切片元素进行排序。它是 Go 实验性 slices 包的一部分,可与有序类型一起使用。
此函数针对性能进行了优化,并提供了一种便捷的方法来排序集合,而无需为基本情况编写自定义排序逻辑。
基本 slices.Sort 示例
slices.Sort
最简单的用法是按升序对整数切片进行排序。该函数会就地修改原始切片。
package main import ( "fmt" "slices" ) func main() { numbers := []int{5, 2, 9, 1, 5, 6} slices.Sort(numbers) fmt.Println("Sorted numbers:", numbers) }
我们创建一个无序数字的切片并对它们进行排序。输出显示数字按升序排列。原始切片已被修改。
排序字符串
slices.Sort
可以按字母顺序对字符串切片进行排序。本示例演示了如何对姓名列表进行排序。
package main import ( "fmt" "slices" ) func main() { names := []string{"Zoe", "Alice", "Bob", "Charlie"} slices.Sort(names) fmt.Println("Sorted names:", names) }
字符串按字典顺序排序。排序区分大小写,在 ASCII 顺序中大写字母排在小写字母之前。
使用自定义比较函数对结构体进行排序
对于自定义类型,我们使用 slices.SortFunc
和一个比较函数。本示例按年龄对人员进行排序。
package main import ( "cmp" "fmt" "slices" ) type Person struct { Name string Age int } func main() { people := []Person{ {"Alice", 25}, {"Bob", 30}, {"Charlie", 20}, } slices.SortFunc(people, func(a, b Person) int { return cmp.Compare(a.Age, b.Age) }) fmt.Println("People sorted by age:", people) }
我们定义一个使用 cmp.Compare
来确定顺序的比较函数。该函数返回 -1、0 或 1,分别表示小于、等于或大于。
降序排序
要按降序排序,我们会反转比较逻辑。本示例按从高到低的顺序对数字进行排序。
package main import ( "cmp" "fmt" "slices" ) func main() { numbers := []int{5, 2, 9, 1, 5, 6} slices.SortFunc(numbers, func(a, b int) int { return cmp.Compare(b, a) // Reverse order }) fmt.Println("Descending order:", numbers) }
通过比较 b 和 a 而不是 a 和 b,我们反转了排序顺序。对于任何可比较的类型,此技术都适用。
使用多重条件进行排序
复杂的排序可以使用多个字段。本示例按姓氏排序,然后按名字排序。
package main import ( "cmp" "fmt" "slices" ) type Person struct { First string Last string } func main() { people := []Person{ {"Alice", "Smith"}, {"Bob", "Johnson"}, {"Alice", "Johnson"}, } slices.SortFunc(people, func(a, b Person) int { if c := cmp.Compare(a.Last, b.Last); c != 0 { return c } return cmp.Compare(a.First, b.First) }) fmt.Println("Sorted people:", people) }
比较首先检查姓氏,然后如果姓氏相同,则回退到名字。这会创建自然的排序顺序。
稳定排序
slices.SortStableFunc
维护相等元素的相对顺序。当保留原始顺序很重要时,这很有用。
package main import ( "cmp" "fmt" "slices" ) type Item struct { Name string Order int // Original position } func main() { items := []Item{ {"A", 1}, {"B", 2}, {"A", 3}, } slices.SortStableFunc(items, func(a, b Item) int { return cmp.Compare(a.Name, b.Name) }) fmt.Println("Stable sorted items:", items) }
两个“A”项都保持了它们原始的相对顺序(1 在 3 之前)。常规排序可能不会为相等元素保留此排序。
性能注意事项
排序函数使用高效的算法。本示例对不同大小的切片进行排序进行基准测试。
package main import ( "fmt" "math/rand" "slices" "time" ) func main() { sizes := []int{100, 10_000, 1_000_000} for _, size := range sizes { slice := make([]int, size) for i := range slice { slice[i] = rand.Intn(size) } start := time.Now() slices.Sort(slice) elapsed := time.Since(start) fmt.Printf("Sorted %d elements in %v\n", size, elapsed) } }
该实现对大多数情况使用优化的快速排序。对于最坏情况的输入,性能会下降到 O(n^2),尽管在实践中这种情况很少见。
来源
本教程通过在各种场景下对不同数据类型进行排序的实际示例,介绍了 Go 中的 slices.Sort
函数。