golang发布新版本了!一起看看golang1.17新特性!

Go1.17简介

最新的 Go 版本 1.17 版本在Go 1.16发布六个月后发布。它的大部分变化都在工具链、运行时和库的实现中。与往常一样,该版本保持了 Go 1对兼容性的承诺。希望几乎所有的 Go 程序都能像以前一样继续编译和运行。

语言的变化

Go 1.17 包括对该语言的三个小改进。

  • 从切片到数组指针的转换s类型表达式[]T现在可以转换为数组指针类型 *[N]T。如果a是此类转换的结果,则范围内的相应索引引用相同的基础元素:&a[i] == &s[i] for 0 <= i < N。如果len(s)小于,则转换会发生恐慌 N
  • unsafe.Add: unsafe.Add(ptr, len)添加len 到ptr并返回更新指针 unsafe.Pointer(uintptr(ptr) + uintptr(len))
  • unsafe.Slice: 对于ptrtype 的表达式*T, unsafe.Slice(ptr, len)返回一个类型[]T的切片,其底层数组从 开始,ptr其长度和容量为len

加入该软件包不安全增强简化编写代码符合unsafe.Pointer安全规则,但规则保持不变。特别是,正确使用的现有程序unsafe.Pointer仍然有效,新程序在使用unsafe.Add或时仍必须遵循规则unsafe.Slice

请注意,从切片到数组指针的新转换是类型转换在运行时可能发生混乱的第一种情况。假设类型转换永远不会恐慌的分析工具应该更新以考虑这种可能性。

编译器

Go 1.17 实现了一种使用寄存器而不是堆栈传递函数参数和结果的新方法。一组具有代表性的 Go 包和程序的基准测试显示,性能提高了约 5%,二进制大小通常减少了约 2%。这是目前在Linux,MacOS和Windows中启用的64位x86架构(的linux/amd64, darwin/amd64windows/amd64端口)。

此更改不会影响任何安全 Go 代码的功能,并且不会影响大多数汇编代码。它可能会影响unsafe.Pointer 访问函数参数时违反规则的代码,或者取决于涉及比较函数代码指针的未记录行为。为了保持与现有汇编函数的兼容性,编译器生成了在新的基于寄存器的调用约定和以前的基于堆栈的调用约定之间进行转换的适配器函数。这些适配器通常对用户不可见,除了在汇编代码中获取 Go 函数的地址或在 Go 代码中使用reflect.ValueOf(fn).Pointer() 或获取汇编函数的地址之外unsafe.Pointer现在将返回适配器的地址。依赖于这些代码指针值的代码可能不再按预期运行。在两种情况下,适配器也可能导致非常小的性能开销:通过func值从 Go 间接调用汇编函数,以及从汇编调用 Go 函数。

运行时堆栈跟踪的格式(在发生未捕获的恐慌时或runtime.Stack调用时打印)得到改进。以前,函数参数根据内存布局打印为十六进制字。现在源代码中的每个参数都单独打印,用逗号分隔。聚合类型(结构、数组、字符串、切片、接口和复杂)参数由花括号分隔。需要注意的是,仅存在于寄存器中而不存储到内存中的参数的值可能不准确。不再打印函数返回值(通常不准确)。

现在可以内联包含闭包的函数。此更改的一个影响是,带有闭包的函数可能会为函数内联的每个位置生成一个不同的闭包代码指针。Go 函数值不能直接比较,但此更改可能会揭示使用reflect 或unsafe.Pointer绕过此语言限制并通过代码指针比较函数的代码中的错误。

链接器

当链接器使用外部链接模式时,这是链接使用 cgo 的程序时的默认设置,并且使用-I选项调用链接器时,该选项现在将作为-Wl,--dynamic-linker选项传递给外部链接器。

核心库

URL查询解析

net/urlnet/http用于接受包 ";"(分号)作为URL查询设置隔板,除了"&"(号)。现在,带有非百分比编码分号的设置net/http将被拒绝,服务器将Server.ErrorLog 在请求 URL 中遇到分号时记录警告 。

例如,在 Go 1.17 之前Query ,URL的方法example?a=1;b=2&c=3会返回 map[a:[1] b:[2] c:[3]],而现在它返回map[c:[3]].

当遇到这样的查询字符串, URL.Query 而 Request.FormValue 忽略包含分号任何设置, ParseQuery 返回剩余的设置和错误,并 Request.ParseForm 与 Request.ParseMultipartForm 返回一个错误,但仍然设置Request基础上,剩余的设置领域。

net/http用户可以使用新的AllowQuerySemicolons 处理程序包装器恢复原始行为 。这也将抑制ErrorLog警告。请注意,如果不同的系统以不同的方式解释缓存键,接受分号作为查询分隔符可能会导致安全问题。有关更多信息,请参阅问题 25192

以上是go1.17的一部分内容,想了解更详细内容的小伙伴,点击传送门查看。

同时也欢迎小伙伴关注本站,一起学习进步!