高端 网站建设,成都网销网站,希爱力跟万艾可哪个猛,WordPress增加下载按钮预期中的Go 2不会有了#xff0c;1.20也算是一个小gap#xff0c;从中可以一窥Go未来的发展之路。对于Go来说#xff0c;未来保持1.x持续演进和兼容性之外#xff0c;重点就是让Go性能更优#xff0c;同时保持大道至简原则#xff0c;使用尽可能容易#xff0c;从这两个…预期中的Go 2不会有了1.20也算是一个小gap从中可以一窥Go未来的发展之路。对于Go来说未来保持1.x持续演进和兼容性之外重点就是让Go性能更优同时保持大道至简原则使用尽可能容易从这两个方面带大家看看你1.20值得关注的特性。
优化相关
编译速度
1.18引入泛型降低了编译速度这一般版本基本上优化和1.17平齐当前1.20的编译也是依赖Go 1.17版本自举。如果没泛型刚需的可以等到1.20稳定后升级。
内存优化area
引入新的内存分配机制arena支持手动管理内存部分场景提升5%-15%可参考golang新特性arena带你起飞。
编译优化pgo
全称Profile-guided optimization (PGO)也是一项新的优化技术通常提升3%-4%简单说就是先跑一遍程序生成pprof文件然后基于此文件引导编译器优化再编译一遍。当前只实现内联的优化后续可能增加多种优化个人理解有点类似离线版本JIT。
发行体积
安装包安装$GOROOT/pkg 目录将不再存储标准库的预编译包存档相比之前减少1/3。
默认禁用 CGO
在没有C toolchain的系统上默认禁用 CGO相比依赖CGO的标准库此情况编译只依赖pure Go。
代码编写
可以看到Go新版本代码编写演进总的原则就是简化写代码的心智负担普通开发者只需要关心实现即可尽可能少的和底层实现绑定。
多error wrap
在1.13基础上增加多error wrap的能力类似功能不用再依赖外部库(hashicorp/go-multierror库等)。使用很简单如下多个%w格式化即可wrap同时支持Is和As
func TestMultiWrap(t *testing.T) {err1 : errors.New(Error 1)err2 : errors.New(Error 2)err3 : errors.New(Error 3)err : fmt.Errorf(%w,%w,%w, err1, err2, err3)fmt.Printf(wrap errors:%v\n, err)fmt.Printf(is err1:%v, is err2:%v, is err3:%v\n,errors.Is(err, err1),errors.Is(err, err2),errors.Is(err, err3))
}输出 wrap errors:Error 1,Error 2,Error 3 is err1:true, is err2:true, is err3:true slice转array
在1.20之前slice转array需要了解底层原理如下实现不是特别直观 slice : []int{1, 2, 3, 4, 5}// 老方法array1 : *(*[5]int)(slice)1.20引入直接转换实现降低新手入门难度更加直观如下操作即可 //新方法// 1.20之前报错 cannot convert slice (variable of type []int) to type [5]intarray2 : [5]int(slice)//array22 : [6]int(slice)//fmt.Printf(Array:%v\n, array22)注意目标数组长度不能大于slice长度否则报错 // panic: runtime error: cannot convert slice with length 5 to array or pointer to array with length 6 bytes string互转
在1.20之前bytes/string互转需要了解底层实现借助unsafe代码来实现如下
func OldBytesToString(b []byte) string {return *((*string)(unsafe.Pointer(b)))
}func OldStringToBytes(s string) []byte {stringHeader : (*reflect.StringHeader)(unsafe.Pointer(s))var b []bytepbytes : (*reflect.SliceHeader)(unsafe.Pointer(b)) // 先引用防止原有string gcpbytes.Data stringHeader.Datapbytes.Len stringHeader.Lenpbytes.Cap stringHeader.Lenreturn b
}1.20中官方提供如下三个函数包装下底层实现
func String(ptr *byte, len IntegerType) string根据数据指针和字符长度构造一个新的 string。func StringData(str string) *byte返回指向该 string 的字节数组的数据指针。func SliceData(slice []ArbitraryType) *ArbitraryType返回该 slice 的数据指针。
以往常用的 reflect.SliceHeader 和 reflect.StringHeader 将会被标注为被废弃。互转代码大大简化可如下实现
func NewBytesToString(b []byte) string {return unsafe.String(b[0], len(b))
}func NewStringToBytes(s string) []byte {return unsafe.Slice(unsafe.StringData(s), len(s))
}时间格式化和比较
在1.20之前时间格式化只能用别扭的2006-01-02 15:04:05语法可能创始人觉得Geek吧扛不住刚需现在终于支持常见的如下三种格式化语法不知道啥时候能把YYmmdd加进来
func TestTimeFormat(t *testing.T) {tm1 : time.Now()fmt.Printf(DateTime-%v\nDateOnly-%v\nTimeOnly-%v\n,tm1.Format(time.DateTime),tm1.Format(time.DateOnly),tm1.Format(time.TimeOnly))
}输出 DateTime-2023-02-09 00:43:13 DateOnly-2023-02-09 TimeOnly-00:43:13 另外就是相比之前的After/Before比较新引入一个Compare方法比较上更加直观和方便
func TestTimeCompare(t *testing.T) {tm1 : time.Now()tm2 : time.Now()c : tm1.Compare(tm2)if c -1 {fmt.Println(tm1 tm2)} else if c 0 {fmt.Println(tm1 tm2)} else if c 1 {fmt.Println(tm1 tm2)}
}参考
代码 https://gitee.com/wenzhou1219/go-in-prod/tree/master/go_120_feature
Go1.20 那些事错误处理优化、编译速度提高、PGO 提效等新特性你知道多少Go 1.20 is released! - The Go Programming LanguageWhat’s New in Go 1.20, Part I: Language ChangesExploring Go’s Profile-Guided OptimizationsPGO 是啥咋就让 Go 更快更猛了GopherCon 2022: Russ Cox - Compatibility: How Go Programs Keep Working: https://www.youtube.com/watch?vv24wrd3RwGo