go在1.21.0新版本特性

1、介绍

众所周知,我们在使用golang的时候没有max和min函数,很多小伙伴在拿go写算法的时候都要去自己简单的构造max和min函数,不过go终于在1.21.0内置 max minclear函数。

2、max 和 min

源码位于/go/src/builtin/builtin.go

// The max built-in function returns the largest value of a fixed number of
// arguments of [cmp.Ordered] types. There must be at least one argument.
// If T is a floating-point type and any of the arguments are NaNs,
// max will return NaN.
func max[T cmp.Ordered](x T, y ...T) T

// The min built-in function returns the smallest value of a fixed number of
// arguments of [cmp.Ordered] types. There must be at least one argument.
// If T is a floating-point type and any of the arguments are NaNs,
// min will return NaN.
func min[T cmp.Ordered](x T, y ...T) T

当go的1.9版本之后加入了泛型,函数内部传入的也是泛型函数,函数入参是cmp.Ordered,cmp这个包也是go1.21.0新增的package,它提供了三个函数,分别是lesscompareisNaN共我们使用。

首先我们看一下Ordered结构体到底是什么

// Ordered is a constraint that permits any ordered type: any type
// that supports the operators < <= >= >.
// If future releases of Go add new ordered types,
// this constraint will be modified to include them.
//
// Note that floating-point types may contain NaN ("not-a-number") values.
// An operator such as == or < will always report false when
// comparing a NaN value with any other value, NaN or not.
// See the [Compare] function for a consistent way to compare NaN values.
type Ordered interface {
 ~int | ~int8 | ~int16 | ~int32 | ~int64 |
  ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
  ~float32 | ~float64 |
  ~string
}

可以看出,在函数入参可以传入上述类型做比较,是可比较类型参数,例如整型、浮点型、字符串等。如遇到不可比较类型返回的就是NaN结果。

不可比较类型就是不能参与运算符的比较,比如slicemapfunction 等,它们不可以作为maxmin的参数传递。但是这些类型可以与nil做比较的。

例1
func main() {
    m := min()
    fmt.Println(m) // invalid operation: not enough arguments for min() (expected 1, found 0)
}

没有传参,会返回错误信息

例2
func main() {
    s := []int{1, 2, 3, 4, 5}
    m := min(s...)
    fmt.Println(m) // invalid operation: invalid use of ... with built-in min
}

传入切片类型依旧报错

例3
func main() {
    var x int
    m := min(x)
    fmt.Println(m) // 0
}

当给函数传递一个参数的时候,返回的结果和入参的值相等

例4
func main() {
    var x, y int = 1, 2
    m := min(x, y)
    fmt.Println(m) // 1
}

同类型比较输出较小的那个

例5
func main() {
    c := min(1, 2.0, 3)
    fmt.Printf("%T\t%v\n", c, c) // float64 1
}

当有整形和浮点型做比较的时候,由整型转换为浮点型,然后再做比较,最终输出的是 1。

例6
func main() {
    t := min("foo", "bar")
    fmt.Println(t) // bar
    t1 := min("", "foo", "bar")
    fmt.Println(t) // ""
}

字符串的比较用的就是按字典序返回最小字符串,如果有空字符串就返回空字符串

特别提示:

  1. 整型参数,minmax 的参数可以交换和组合。
  2. 字符串类型参数,minmax 的参数逐个字节比较,得出最小/最大的字符串,参数可以交换和组合。
  3. 浮点型参数-0.00.0 作为参数,-0.0 小于 0.0;负无穷大,小于任意其它数值;正无穷大,大于任意其它数值。
  4. minmax 的任意参数是 NaN,则返回结果是 NaN (“not-a-number”) 值。

3、clear函数

先看源码

// The clear built-in function clears maps and slices.
// For maps, clear deletes all entries, resulting in an empty map.
// For slices, clear sets all elements up to the length of the slice
// to the zero value of the respective element type. If the argument
// type is a type parameter, the type parameter's type set must
// contain only map or slice types, and clear performs the operation
// implied by the type argument.
func clear[T ~[]Type | ~map[Type]Type1](t T)

我们可以看见,clear函数的参数也是泛型函数,入参为mapslice,如果是 map,则删除 map 中的所有元素,返回一个空 map;如果是 slice,则将 slice 中的所有元素改为切片类型的零值。

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

可以看出,长度不变,所有元素变为切片的零值

例2
func main() {
    m := map[string]int{"go": 100, "php": 80}
    fmt.Printf("len=%d\tm=%+v\n", len(m), m) // len=2   m=map[go:100 php:80]
    clear(m)
    fmt.Printf("len=%d\tm=%+v\n", len(m), m) // len=0   m=map[]
}

使用clear删除map的时候吧map里面的元素都删除了,长度变为0了。

在项目开发中,我们可以使用函数 clear 删除 map 中的元素,替代通过循环遍历调用 delete 删除 map 中的元素;使用函数 clearslice 中的元素的值修改为切片类型的零值,替代通过循环遍历修改切片中的元素的值为切片类型的零值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值