• Golang1.21更新内容全面介绍~


    我的掘金平台原文地址Golang1.21更新内容全面介绍~

    前言

    在Golang1.21这一次更新中,主要更新内容为:

    • for range的一个语义变更 、

    • 新加入max、min、clear方法、

    • contenxt增添api、

    • WASI的支持

    本文主要带大家熟悉这些变更的内容~


    1.for语义的变更

    首先在go中for range其实有一个比较坑的地方

    举一个简单的例子

    
    printRes:=[]func(){}
    for _,v:=range []int{1,2,3,4,5}{
       printRes=append(printRes,func(){
          fmt.Print(v)
       })
    }
    for _,v:=range printRes{
       v()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    不知道for这个坑的同学可能会认为结果应该为12345,但实际上它的结果是55555

    其原因就是这里的循环遍历使循环变量每次循环
    循环遍历始终是同一个v这才导致了最后的结果都是一致的,要想达到使循环变量每次迭代而不是每次循环其实也不难,只需要在每次循环时都新变量去重新赋值就好了v:=v

    而1.21也是决定了重新定义循环的语义,让其是每次迭代。在1.21当中我们只需要在运行时额外加一个 GOEXPERIMENT=loopvar构建程序即可

    2.新增max,min,clear函数

    在1.21版本go也是基于泛型新增了maxmin函数,支持多种类型,多参数,在以前都需要自己去写这两个方法~

    带大家看一下源码

    // 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    //支持的参数类型
    type Ordered interface {
       ~int | ~int8 | ~int16 | ~int32 | ~int64 |
          ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
          ~float32 | ~float64 |
          ~string
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    举例

    fmt.Println(max(1,uint(7),8))  //-->8
    
    • 1

    除去max(),min()。还有一个clear()的方法,顾名思义就是对传入的变量进行一个数据回收

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

    可以看到该方法主要服务于slice与map类型
    对于切片,clear会将其数据变为默认值0,但是len,cap都不变

    s:=[]int{1,2,3,4,5,6,7,8,9,10}
    clear(s)
    fmt.Printf("s:%v,len:%v,cap:%v",s,len(s),cap(s))
    
    //s:[0 0 0 0 0 0 0 0 0 0],len:10,cap:10
    
    • 1
    • 2
    • 3
    • 4
    • 5

    而对于map,结果是这样的

    m:=make(map[string]int,10)
    m["a"]=1
    fmt.Printf("m:%v,len:%v\n",m,len(m))
    clear(m)
    fmt.Printf("m:%v,len:%v",m,len(m))
    
    //m:map[a:1],len:1
    //m:map[],len:0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    数据清空,桶也清空~


    3.contenxt更新

    context应该不必我多介绍了,Go语言特别常用的用于不同go协程之间的通信,收发取消信号、截至信号、元数据等上下文。

    context这次更新主要是针对cancel()发送取消信号增加了一个取消原因以及回调函数的增添

    func WithCancelCause(parent Context) (ctx Context, cancel CancelCauseFunc)
    
    func WithTimeoutCause(parent Context, timeout time.Duration, cause error) (Context, CancelFunc)
    
    func WithDeadlineCause(parent Context, d time.Time, cause error) (Context, CancelFunc)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如图在三个api中形参都增添了一个cause的错误类型,当cancel()调用或者超时后那么context.Cause(ctx)
    方法就会获得我们自定义的错误,而非默认的ctx.Err()中的context deadline exceeded。这样做的好处显而易见,当我们程序出错的,根据我们自定义的错误去追踪错误显然会比默认的context deadline exceeded更精确

    代码举例:

    myctxErr:=fmt.Errorf("自定义ctxErr错误")
    
    
    ctx,cancel:=context.WithTimeoutCause(context.Background(),1*time.Second,myctxErr)
    defer cancel()
    time.Sleep(2*time.Second)
    fmt.Println(context.Cause(ctx))
    
    //自定义ctxErr错误
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    而关于回调函数,

    func AfterFunc(ctx Context, f func()) (stop func() bool)

    其作用是在cancel取消或者超时后Evict

    在一些场景下我们常常要用goroutine+select+channel这套组合拳来实现监听取消的行为并为此做出后续的业务

    而有了这个回调函数可以让我们用更简洁的代码来实现这一功能

    举例:

    func main(){
       myctxErr:=fmt.Errorf("自定义ctxErr错误")
       ctx,cancel:=context.WithTimeoutCause(context.Background(),5*time.Second,myctxErr)
       context.AfterFunc(ctx,func1)
       defer cancel()
       time.Sleep(6*time.Second)
       fmt.Println(context.Cause(ctx))
    }
    
    
    //evictEvent
    func func1()  {
       fmt.Println(666)
    }
    
    //666
    //自定义ctxErr错误
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    4.WASI支持

    Go1.21 起,Go 将会支持 WASI 。预计先支持 WASI Preview1 标准,后续 WASI Preview2 成熟后会继续支持新标准。

    而WASI全称为WebAssembly System Interface
    不熟悉想了解的朋友可以观看WASI 前瞻 - 知乎 (zhihu.com)这篇文章

    以上就是我分享所有内容,希望能够帮助到大家~~

  • 相关阅读:
    SSM整合之Mybatis笔记(MyBatis的逆向工程(代码生成器))(P058—P059)
    洛谷 Array 数论
    react--redux
    dreamweaver网页设计作业制作 学生个人网页单页 WEB静态网页作业模板 大学生个人主页博客网页代码 dw个人网页作业成品简单页面
    虾皮shopee根据ID取商品详情 API 返回值说明
    JDBC详解
    1422. 分割字符串的最大得分
    实再高度为设备高度的100%布局
    通用后台管理系统前端界面Ⅸ——数据表格渲染及处理+前端分页
    React 钩子汇总
  • 原文地址:https://blog.csdn.net/qq_51898139/article/details/132767901