ZetCode

Golang slices.Min

最后修改于 2025 年 4 月 20 日

本教程将讲解如何在 Go 中使用 `slices.Min` 函数。我们将通过实际示例涵盖查找切片中的最小元素。

`slices.Min` 函数返回切片中的最小元素。它是 Go 实验性 slices 包的一部分,可与有序类型一起使用。

此函数对于查找数字、字符串或其他可比较类型集合中的最小值非常有用。如果切片为空,它将触发 panic。

基本的 slices.Min 示例

`slices.Min` 最简单的用法是查找切片中的最小数字。该函数适用于任何支持比较的有序类型。

basic_min.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    numbers := []int{3, 1, 4, 1, 5, 9, 2, 6}
    
    minNum := slices.Min(numbers)
    fmt.Println("Minimum number:", minNum)
}

我们创建一个整数切片并查找最小值。函数返回 1,它在切片中出现两次。仅考虑第一次出现。

查找最小字符串

`slices.Min` 可以查找切片中字典序最小的字符串。字符串比较遵循 Unicode 码点顺序。

string_min.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    fruits := []string{"apple", "banana", "cherry", "apricot"}
    
    minFruit := slices.Min(fruits)
    fmt.Println("First fruit alphabetically:", minFruit)
}

该函数逐个字符比较字符串。 "apricot" 在 Unicode 顺序中排在 "apple" 之前,因为 'a' == 'a' 但 'p' < 'r'。

使用自定义类型

要将 `slices.Min` 与自定义类型一起使用,它们必须实现 `Ordered` 约束。此示例展示了一个自定义有序类型。

custom_type.go
package main

import (
    "fmt"
    "slices"
)

type Temperature float64

func main() {
    temps := []Temperature{22.5, 18.3, 25.7, 16.8, 20.1}
    
    minTemp := slices.Min(temps)
    fmt.Println("Minimum temperature:", minTemp)
}

我们的 `Temperature` 类型基于 `float64`,它已经实现了排序。该函数能正确找到最低的温度值。

处理空切片

在空切片上调用 `slices.Min` 会导致 panic。我们应该始终先检查切片长度,以避免运行时错误。

empty_slice.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    var empty []int
    
    if len(empty) == 0 {
        fmt.Println("Cannot find min of empty slice")
        return
    }
    
    // This would panic if executed:
    // min := slices.Min(empty)
    // fmt.Println(min)
}

代码演示了正确的空切片处理。当切片可能为空时,在调用 `slices.Min` 之前务必检查长度。

使用自定义比较查找最小值

对于没有内置排序的复杂类型,我们可以使用 `slices.MinFunc`。此示例查找长度最短的字符串。

custom_comparison.go
package main

import (
    "fmt"
    "slices"
)

func main() {
    words := []string{"apple", "banana", "fig", "cherry"}
    
    shortest := slices.MinFunc(words, func(a, b string) int {
        return len(a) - len(b)
    })
    
    fmt.Println("Shortest word:", shortest)
}

`slices.MinFunc` 接受一个比较函数,当 a < b 时返回负值。在这里,我们比较字符串长度而不是字典序。

性能注意事项

`slices.Min` 的时间复杂度为 O(n)。对于大型切片,如果性能至关重要,请考虑并行处理。

performance.go
package main

import (
    "fmt"
    "math/rand"
    "slices"
    "time"
)

func main() {
    rand.Seed(time.Now().UnixNano())
    largeSlice := make([]int, 1_000_000)
    for i := range largeSlice {
        largeSlice[i] = rand.Intn(1_000_000)
    }
    
    start := time.Now()
    min := slices.Min(largeSlice)
    elapsed := time.Since(start)
    
    fmt.Printf("Found min %d in %v\n", min, elapsed)
}

该示例对查找大型切片中的最小值进行了基准测试。该操作是线性的,但对于典型用例仍然很快。

实际示例:学生成绩

这个实际示例查找班级中的最低分数。它通过错误处理和自定义类型演示了实际使用。

student_grades.go
package main

import (
    "fmt"
    "slices"
)

type Grade int

func main() {
    grades := []Grade{85, 92, 78, 90, 65, 88, 72}
    
    if len(grades) == 0 {
        fmt.Println("No grades available")
        return
    }
    
    lowest := slices.Min(grades)
    fmt.Println("Lowest grade in class:", lowest)
    
    if lowest < 60 {
        fmt.Println("Warning: At least one failing grade")
    }
}

我们定义了一个 `Grade` 类型并查找最小值。代码包括正确的空切片检查以及基于结果的后续操作。

来源

Go 实验性切片包文档

本教程通过实际示例,涵盖了 Go 中的 `slices.Min` 函数,展示了在各种场景和数据类型中查找最小元素的方法。

作者

我叫 Jan Bodnar,是一位热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有 Go 教程