Go 1.21 新内置函数:min、max 和 clear

max 函数

func max[T cmp.Ordered](x T, y ...T) T

这是一个泛型函数,用于从一组值中寻找并返回 最大值,该函数至少要传递一个参数。在上述函数签名中,T 表示类型参数,它必须满足 cmp.Ordered 接口中定义的数据类型要求,该接口的定义如下所示

go 复制代码
type Ordered interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 |
		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
		~float32 | ~float64 |
		~string
}

使用示例

了解了 max 函数的定义后,让我们一起来学习如何使用它。

go 复制代码
package main

import "fmt"

func main() {
	var a1, a2, a3 int64 = 1, 2, 3
	maxA := max(a1, a2, a3)
	fmt.Printf("%T, %d\n", maxA, maxA) // int64, 3

	var f1, f2, f3 float64 = 1.0, 2.0, 3.0
	maxF := max(f1, f2, f3)
	fmt.Printf("%T, %.1f\n", maxF, maxF) // float64, 3.0

	var s1, s2, s3 string = "aaa", "aab", "aac"
	maxS := max(s1, s2, s3)
	fmt.Printf("%T, %s\n", maxS, maxS) // string, aac
}

在上述示例中,使用了 max 函数分别对 int64、float64 和 string 类型的一组值进行比较并获取最大值,值得注意的地方是 string 类型的比较原理,它是 基于字节的字典顺序对字符串进行比较。

min 函数

func min[T cmp.Ordered](x T, y ...T) T

该函数与 max 函数的功能相反,用于从一组值中寻找并返回 最小值,同样传递进来的值类型也必须满足 cmp.Ordered 接口中定义的数据类型要求。

使用示例

go 复制代码
package main

import "fmt"

func main() {
	var a1, a2, a3 int64 = 1, 2, 3
	minA := min(a1, a2, a3)
	fmt.Printf("%T, %d\n", minA, minA) // int64, 1

	var f1, f2, f3 float64 = 1.0, 2.0, 3.0
	minF := min(f1, f2, f3)
	fmt.Printf("%T, %.1f\n", minF, minF) // float64, 1.0

	var s1, s2, s3 string = "aaa", "aab", "aac"
	minS := min(s1, s2, s3)
	fmt.Printf("%T, %s\n", minS, minS) // string, aaa
}

在上述示例中,使用了 min 函数分别对 int64、float64 和 string 类型的一组值进行比较并获取最小值,string 类型的比较原理与 max 函数的比较原理相同。

clear 函数

func clear[T ~[]Type | ~map[Type]Type1](t T)

该函数接收一个参数 t,用于清空变量 t (类型为 slice 或 map) 中的元素。

如果传递的是切片类型变量,则会将切片的所有元素赋值为该切片类型的零值;

如果传递的是 map 类型变量,则会清空 map 类型变量的元素;

如果传递的是自定义泛型类型(例如 type MySlice[T any] []T),则类型集中所有类型必须是 slice 或 map。

使用示例

go 复制代码
package main

import "fmt"

type MySlice[T any] []T  
  
type MyMap[K comparable, V any] map[K]V

func main() {
	s := []int{1, 2, 3, 4}
	clear(s)
	fmt.Printf("len: %d, cap: %d, elems: %v\n", len(s), cap(s), s) // len: 4, cap: 4, elems: [0 0 0 0]

	m := map[string]int{"Apple": 1, "Banana": 2}
	clear(m)
	fmt.Printf("len: %d, elems: %v\n", len(m), m) // len: 0, elems: map[]

	// 自定义泛型切片类型变量
	mySlice := MySlice[string]{"公众号:Go技术干货", "陈明勇", "Gopher"}
	clear(mySlice)
	fmt.Printf("len: %d, cap: %d, elems: %v\n", len(mySlice), cap(mySlice), mySlice) // len: 3, cap: 3, elems: [  ]

	// 自定义泛型 map 类型变量
	myMap := MyMap[string, int]{"Apple": 1, "Banana": 2}
	clear(myMap)
	fmt.Printf("len: %d, elems: %v\n", len(myMap), myMap) // len: 0, elems: map[]
}

在上述示例中,演示了如何通过 clear 函数对切片或 map 变量进行删除或清空操作,clear 函数不仅能接收 slice 和 map 类型的变量,还能接收我们所自定义的泛型类型参数,但是在使用时必须确保类型参数集中所有类型必须是 slice 或 map。

值得注意的是:使用 clear 函数清空切片元素时,并不会真正的删除其中的元素,而是会将所有元素都设置为对应类型的零值。这意味着切片仍然保留其原始长度和容量,但元素的内容被清空。

小结

本文详细介绍了 Go 1.21.0 版本中新增的内置函数 max、min、和 clear。通过使用这些函数,我们无需再自行定义比较大小或清空切片以及 map 变量的函数。

遗憾的是,要彻底清空切片并将长度和容量都置为 0,仍然需要另外封装一个函数来实现。因为 clear 函数只是将切片的元素赋值为相应类型的零值,而未改变其长度和容量。

相关推荐
意倾城41 分钟前
Spring Boot 配置文件敏感信息加密:Jasypt 实战
java·spring boot·后端
火皇40542 分钟前
Spring Boot 使用 OSHI 实现系统运行状态监控接口
java·spring boot·后端
rylshe13141 小时前
在scala中sparkSQL连接mysql并添加新数据
开发语言·mysql·scala
小宋加油啊1 小时前
Mac QT水平布局和垂直布局
开发语言·qt·macos
薯条不要番茄酱1 小时前
【SpringBoot】从零开始全面解析Spring MVC (一)
java·spring boot·后端
MyhEhud1 小时前
kotlin @JvmStatic注解的作用和使用场景
开发语言·python·kotlin
想睡hhh1 小时前
c++进阶——哈希表的实现
开发语言·数据结构·c++·散列表·哈希
Clown952 小时前
Go语言爬虫系列教程(一) 爬虫基础入门
开发语言·爬虫·golang
Watermelo6172 小时前
前端如何应对精确数字运算?用BigNumber.js解决JavaScript原生Number类型在处理大数或高精度计算时的局限性
开发语言·前端·javascript·vue.js·前端框架·vue·es6
Aric_Jones4 小时前
lua入门语法,包含安装,注释,变量,循环等
java·开发语言·git·elasticsearch·junit·lua