Go 1.21.0 带来了什么新特性?min 和 max 内置函数解析

1.21.0 是 Go 语言的最新版本,它将在 2023 年 8 月发布,会带来了一些语言和的变化。其中一个值得关注的变化是增加了两个新的内置函数 min 和 max,用来对任意可比较类型进行最小值和最大值的操作。这是很常见的需求,现在有内置实现了。本文将介绍这两个函数的背景、规范、实现原理和使用示例。

增加这两个函数的背景

在 Go 语言中,有很多情况需要对一组值进行最小值或最大值的操作,比如排序、统计、筛选等。然而,Go 语言没有提供直接的方法来实现这个功能,需要自己编写循环来完成。(标准库 math 有对应的函数,但只支持接受 float64 类型。)

但这个确实很常见的需求。为此,Go 1.21.0 引入了两个新的内置函数 min 和 max,它们可以对任意可比较类型进行最小值或最大值的操作,无需编写循环或引入第三方库。

长什么样?

根据 Go builtin ,min 和 max 的函数原型如下:

//Themaxbuilt-infunctionreturnsthelargestvalueofafixednumberof
//argumentsof[cmp.Ordered]types.Theremustbeatleastoneargument.
//IfTisafloating-pointtypeandanyoftheargumentsareNaNs,
//maxwillreturnNaN.
funcmax[Tcmp.Ordered](xT,y...T)T

//Theminbuilt-infunctionreturnsthesmallestvalueofafixednumberof
//argumentsof[cmp.Ordered]types.Theremustbeatleastoneargument.
//IfTisafloating-pointtypeandanyoftheargumentsareNaNs,
//minwillreturnNaN.
funcmin[Tcmp.Ordered](xT,y...T)T

这两个函数的实现原理

min 和 max 是内置函数,它们的实现是在编译器层面完成的,而不是在运行时。具体来说,它们是在编译器的 SSA (Static Single Assignment) 阶段进行转换的,将 min 和 max 的调用转换为对应的循环。这样做的好处是可以避免引入新的运行时函数,也可以让编译器有更多的优化空间。

具体的实现代码在 /cmd/compile/internal/types2/builtins.go 中:(部分代码)

i,a:=rangeargs{
a.mode==invalid{
return
}

if!allOrdered(a.typ){
check.errorf(a,InvalidMinMaxOperand,invalidArg+"%scannotbeordered",a)
return
}

//Thefirstargumentisalreadyinxandthere'snothinglefttodo.
ifi>0{
check.matchTypes(x,a)
ifx.mode==invalid{
return
}

if!Identical(x.typ,a.typ){
check.errorf(a,MismatchedTypes,invalidArg+"mismatchedtypes%s(previousargument)and%s(typeof%s)",x.typ,a.typ,a.expr)
return
}

ifx.mode==constant_&&a.mode==constant_{
ifconstant.Compare(a.val,op,x.val){
*x=*a
}
}else{
x.mode=value
}
}
}

可以看到,编译器将 min 的调用转换为一个循环,从第二个参数开始遍历切片,并与第一个参数比较大小,更新最小值/最大值

使用示例

min 和 max 函数的使用非常简单,只需要将要比较的值作为参数传入即可。

下面是一些使用示例:(在线运行地址 https://go.dev/play/p/AQ6HD_gfame?v=gotip)

packagemain

import(
"fmt"
"math"
)

funcmain(){
//比较整数
fmt.Println(min(1,2,3))//1
fmt.Println(max(1,2,3))//3

//比较浮点数
fmt.Println(min(1.5,2.5,3.5))//1.5
fmt.Println(max(1.5,2.5,3.5))//3.5

//浮点数包含NaN
fmt.Println(min(1.5,math.NaN(),3.5))//NaN
fmt.Println(max(1.5,math.NaN(),3.5))//NaN

//比较字符串
fmt.Println(min("apple","banana","cherry"))//apple
fmt.Println(max("apple","banana","cherry"))//cherry
}

输出结果:

1
3
1.5
3.5
NaN
NaN
apple
cherry

可以看到,min 和 max 函数可以方便地对不同类型的值进行最小值和最大值的操作,无需编写额外的代码。

总结

本文介绍了 Go 1.21.0 新增的两个内置函数 min 和 max,它们可以对任意可比较类型进行最小值和最大值的操作。目前 Go1.21.0 还未发布,其中的具体实现可能会发生变化。

学习资料获取

Go 1.21.0 带来了什么新特性?min 和 max 内置函数解析
Go 1.21.0 带来了什么新特性?min 和 max 内置函数解析

识别添加助理回复关键字“资料”就可打包全部带走不备注不发教程哦!

给TA打赏
共{{data.count}}人
人已打赏
运维笔记

深入解析go channel各状态下的操作结果

2023-10-10 18:33:34

运维笔记

监控系统看这一篇就够了!Zabbix、Prometheus等常见监控教程

2023-10-10 18:33:41

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索