go 1.18 系列(1)- 变化说明

2022-05-09 13:29:15 浏览数 (1)

go 1.18 系列(1)- 变化说明

go 1.18正式发布了,这个版本比较重要,所以需要详细指导这个版本改了些什么。

第一篇是对发布的文档进行了学习,后续会针对比较重要的部分进行详细分析和学习。包括:

  1. 泛型
  2. 模糊测试
  3. 工作空间

go 1.18 doc

Go 1.18 正式发布了!支持泛型、性能优化

语法规范

对语言、工具链的实现、运行时和库的更改,对GO 1兼容。

泛型

go1.18 最明显也是最重要的就是泛型,这个新语言有大量未在生产环境中进行测试的新代码,生产环境中部署泛型代码时请谨慎行事

以下是最明显变化的列表

  • 函数 和 类型声明 的语法,现在接受**类型参数**
  • 参数化函数和类型可以通过在它们后面加上方括号中的类型参数列表来实例化
  • 新标记~已添加到一组 操作符和标点符号 中
  • 接口类型的语法现在允许嵌入任意类型(不仅仅是接口的类型名称)以及 union 和 ~T 类型元素。,这样的接口只能用作类型约束。
  • 新的 预声明标识符 any是空接口的别名。它可以用来代替 interface{}.
  • 新的 预声明标识符 comparable是一个接口,表示可以使用==or比较的所有类型的集合!=。它只能用作(或嵌入)类型约束。

有三个使用泛型的实验包可能有用。这些包在 x/exp 存储库中;他们的 API 不在 Go 1 保证范围内

  • golang.org/x/exp/constraints:对通用代码有用的约束,例如 constraints.Ordered.
  • golang.org/x/exp/slices:对任何元素类型的切片进行操作的通用函数集合。
  • golang.org/x/exp/maps:对任何键或元素类型的映射进行操作的通用函数集合。

当前的泛型实现具有以下已知限制:

  • Go 编译器无法处理泛型函数或方法中的类型声明,计划在 Go 1.19 中取消这个限制。
  • Go 编译器不接受具有预声明函数 real、imag 和 complex 的参数类型的参数,计划在 Go 1.19 中取消这个限制。
  • 如果 m 由 P 的约束接口显式声明,Go 编译器仅支持在类型参数类型 P 的值 x 上调用方法 m。 类似地,方法值 x.m 和方法表达式 P.m 也仅在 m 由 P 显式声明时才受支持,即使 m 可能在 P 的方法集中,因为 P 中的所有类型都实现了 m,计划在 Go 1.19 中取消这个限制。
  • Go 编译器不支持访问结构字段 x.f,其中 x 是类型参数类型,即使类型参数的类型集中的所有类型都具有字段 f,计划在 Go 1.19 中取消这个限制。
  • 不允许将类型参数或指向类型参数的指针作为结构类型中的未命名字段嵌入,同样地,也不允许在接口类型中嵌入类型参数。
  • 具有多个 term 的 union 元素可能不包含具有非空方法集的接口类型。

理解

怎么理解上面这啰嗦的东西呢。

函数: 定义中添加了 [ TypeParameters ]
代码语言:javascript复制
FunctionDecl = "func" FunctionName [ TypeParameters ] Signature [ FunctionBody ] .
FunctionName = identifier .
FunctionBody = Block .

如果函数声明指定类型参数,则函数名称表示泛型函数。泛型函数必须先被实例化,然后才能被调用或用作值。

代码语言:javascript复制
func min[T ~int|~float64](x, y T) T {
	if x < y {
		return x
	}
	return y
}

也就是说这个T必须指定类型,先实例化为接受底层使用int和float64两种类型的类型,这样这个函数就是一个泛型函数。

类型声明:
代码语言:javascript复制
TypeDef = identifier [ TypeParameters ] Type .

例子:任意类型的Tree

代码语言:javascript复制
type Tree[T any] struct {
	left, right *Tree[T]
	value       T
}

现在上面这两种都接受类型参数 [ TypeParameters ]

参数化函数和类型实例化

说的是如1中,T实例化为接受基类型是int和float64的类型,参数x,y的类型也是这个。

~ 符号
代码语言:javascript复制
type Float interface {
	~float32 | ~float64
}

type MyFloat float64

f := min(MyFloat(1), MyFloat(2))

现在MyFloat虽然是自己定义的, 但是基础类型是float64,就可以将这个类型传入min函数中使用。

代码语言:javascript复制
func min[T int|float64](x, y T) T {
	// ...
}

如果Float定义中没有使用~, 那么MyFloat就不能传入min函数使用,编译器会任务他们不是一个类型

接口类型

定义中添加了

代码语言:javascript复制
InterfaceType  = "interface" "{" { InterfaceElem ";" } "}" .
InterfaceElem  = MethodElem | TypeElem .
MethodElem     = MethodName Signature .
MethodName     = identifier .
TypeElem       = TypeTerm { "|" TypeTerm } .
TypeTerm       = Type | UnderlyingType .
UnderlyingType = "~" Type .

例子:

代码语言:javascript复制
type Float interface {
	~float32 | ~float64
}

这样这个接口Float就变成了一个约束。 可以使用 | 分割的Type分割,也可以添加~变为基类型。

any
代码语言:javascript复制
// any is an alias for interface{} and is equivalent to interface{} in all ways.
type any = interface{}

any 就是一个接口,按我的理解是在泛型使用接口就用any, 其他原有还是使用interface{}, 不然原有低版本情况就会出一些问题,当然仁者见仁了。

切换到Go 1.18后的第一件事:将interface{}全部替换为any

comparable
代码语言:javascript复制
// comparable is an interface that is implemented by all comparable types
// (booleans, numbers, strings, pointers, channels, arrays of comparable types,
// structs whose fields are all comparable types).
// The comparable interface may only be used as a type parameter constraint,
// not as the type of a variable.
type comparable interface{ comparable }

也是一个接口,但是这个接口只能用在 ==!= 这种比较类型,作为这种类型约束

3个约束包

这三个就是官方暂时使用的类型约束,后续应该会添加到源码里。

这里就定义了很多基类型,这样可以方便使用。在写代码的时候记得用就好,别什么都自己又定义一遍。

工具

模糊测试

Go 1.18 包括 fuzzing(模糊测试) 的实现,如 fuzzing 提案 所述,详情请参阅 fuzzing 教程 以开始使用。

这部分详细内容会在第三篇文章中进行学习和总结

注意,模糊测试会消耗大量内存,并且可能会影响机器运行时的性能。

另请注意,模糊引擎在运行时会将扩展测试覆盖率的值写入模糊缓存目录 $GOCACHE/fuzz。目前对可以写入模糊缓存的文件数量或总字节数没有限制,因此可能会占用大量存储空间(可能为 GB 级别)。

bug修复

  1. Go 1.18 编译器现在可以正确报告declared but not used在函数文字中设置但从未使用过的变量的错误
  2. Go 1.18 编译器现在在将如 '1' << 32 之类的符文常量表达式作为参数传递给预声明函数 print 和 println 时会报告溢出。

修改都很简单,使用 go vet 然后修改成正确的就好了。

Ports

AMD64

Go 1.18 引入了新的GOAMD64环境变量,它在编译时选择 AMD64 架构的最低目标版本,允许的值为v1、 v2、v3或v4,默认是v1。

RISC-V

Linux 上的 64 位 RISC-V 架构(linux/riscv64 端口)现在支持 c-archive 和 c-shared 构建模式。

Linux (这个注意一下老系统)

Go 1.18 需要 Linux 内核版本 2.6.32 或更高版本。

Windows

windows/arm 和 windows/arm64 端在支持非合作抢占,有希望解决在调用 Win32 函数时遇到的一些细微的 bug,这些bug在很长一段时间内会阻塞。

iOS

在 iOS(ios/arm64 端口)和在基于 AMD64 的 macOS(ios/amd64 端口)上运行的 iOS 模拟器上,Go 1.18 现在需要 iOS 12 或更高版本; 已停止支持以前的版本。

FreeBSD

Go 1.18 是支持 FreeBSD 11.x 的最后一个版本,Go 1.19 需要 FreeBSD 12.2 或 FreeBSD 13.0 。

性能提升

由于 Go1.17 中寄存器 ABI 调用约定扩展到了 RM64 / Apple M1 / PowerPC 64 架构,因此 Go1.18 对这几个架构包含了高达 20% 的 CPU 性能提升。

执行命令

go get

go get 现在致力于调整go.mod. 实际上,该 -d标志始终处于启用状态。要在当前模块的上下文之外安装最新版本的可执行文件, 请使用 go install example.com/cmd@latest. 可以使用任何 版本查询 来代替latest. go get现在在module外使用时会报告错误,因为没有go.mod要更新的文件, 在 GOPATH 模式下(带有 GO111MODULE=off),go get仍然像以前一样构建和安装包。

自动go.mod和go.sum更新

go mod graph, go mod vendor, go mod verify, 不在自动更新 go.mod 和 go.sum go get, go mod tidy, go mod download 这三个命令才会更新

go version

此外,该go命令嵌入了有关构建的信息,包括构建和工具标签(用 设置-tags)、编译器、汇编器和链接器标志(-gcflags如CGO_CFLAGS)。 VCS 和构建信息都可以使用 go version -m file或 runtime/debug.ReadBuildInfo(对于当前运行的二进制文件)或新debug/buildinfo 包与模块信息一起读取。

要从使用go1.18 构建的二进制文件中读取版本信息,请使用1.18 中的go version命令和 debug/buildinfo包。go

go mod download

go.mod文件指定go 1.17 或更高,go mod download现在不带参数只下载主模块文件中明确需要go.mod的模块的源代码。 要下载传递依赖项的源代码,请使用 go mod download all.

go mod vendor

该go mod vendor子命令现在支持-o设置输出目录的标志。(其他go命令vendor在加载包时仍然从模块根目录读取-mod=vendor)

go mod tidy

该go mod tidy命令现在在文件中为模块保留了额外的校验和,这些go.sum模块需要源代码来验证每个导入的包是否仅由构建列表中的一个模块提供

go work (工作区这个单独会写)

该go命令现在支持“工作区”模式。如果 go.work在工作目录或父目录中找到文件,或者使用GOWORK 环境变量指定文件, 它将使go命令进入工作区模式。 在工作区模式下,该go.work文件将用于确定用作模块解析根的主模块集,而不是使用通常找到的go.mod 文件来指定单个主模块。 有关更多信息,请参阅 go work 文档。

go build -asan

该go build命令和相关命令现在支持一个-asan标志,该标志可以与使用地址清理程序(C 编译器选项-fsanitize=address)编译的 C(或 C )代码进行互操作。

go test

该go命令现在支持上述新的模糊测试支持的附加命令行选项:

  • go test支持 -fuzz、-fuzztime和 -fuzzminimizetime选项。有关这些的文档,请参阅 go help testflag。
  • go clean支持一个-fuzzcache 选项。有关文档,请参阅 go help clean。

//go:build线条

Go 1.17 引入了//go:build行作为编写构建约束的更易读的方式,而不是// build行。从 Go 1.17 开始,gofmt添加//go:build行以匹配现有 build行并使它们保持同步,同时go vet在它们不同步时进行诊断。

由于 Go 1.18 的发布标志着对 Go 1.16 支持的结束,所有支持的 Go 版本现在都可以理解//go:build行了。在 Go 1.18 中,go fix现在删除了 模块声明或稍后在其文件 中的现已过时的// build行

Gofmt

gofmt现在同时读取和格式化输入文件,GOMAXPROCS进行内存限制. 在具有多个 CPU 的机器上,gofmt现在应该明显更快。

Vet

vue 现在支持泛型

例如,vet报告格式错误

代码语言:javascript复制
func Print[T ~int|~string](t T) {
	fmt.Printf("%d", t)
}

因为它会报告非通用等价的格式错误 Print[string]:

代码语言:javascript复制
func PrintString(x 字符串) {
	fmt.Printf("%d", x)
}
现有检查器的精度改进

cmd/vet检查器 、copylock、printf、 sortslice和testinggoroutine都tests 进行了适度的精度改进,以处理额外的代码模式。

这可能会导致现有包中新报告的错误。例如, printf检查器现在跟踪通过连接字符串常量创建的格式化字符串。所以vet会报错:

代码语言:javascript复制
 // fmt.Printf formatting directive %d is being passed to Println.
  fmt.Println("%d" ` ≡ x (mod 2)` "n", x%2)

运行 (这个没太懂,但是也一般用不到)

在确定运行频率时,垃圾收集器现在包括垃圾收集器工作的非堆源(例如堆栈扫描)。因此,当这些来源很重要时,垃圾收集器的开销更容易预测。对于大多数应用程序,这些更改可以忽略不计;然而,一些 Go 应用程序现在可能比以前使用更少的内存并花费更多时间在垃圾收集上,反之亦然。预期的解决方法是 GOGC在必要时进行调整。

运行时现在可以更有效地将内存返回给操作系统,并因此被调整为更积极地工作。

Go 1.17 通常改进了堆栈跟踪中参数的格式,但可能会为寄存器中传递的参数打印不准确的值。?这在 Go 1.18 中通过在每个可能不准确的值后 打印一个问号 ( ) 得到了改进。

内置函数append现在在决定切片必须分配新的底层数组时增加多少时使用稍微不同的公式。新公式不太容易出现分配行为的突然转变。

编译器

Go 1.17实现了一种在选定操作系统的 64 位 x86 架构上使用寄存器而不是堆栈来传递函数参数和结果的新方法。Go 1.18 扩展了支持的平台,包括 64 位 ARM ( GOARCH=arm64)、大端和小端 64 位 PowerPC ( GOARCH=ppc64, ppc64le),以及GOARCH=amd64所有操作系统上的 64 位 x86 架构 ( )。在 64 位 ARM 和 64 位 PowerPC 系统上,基准测试显示典型的性能提升 10% 或更多。

编译器现在可以内联包含范围循环或标记为循环的函数。

新的-asan编译器选项支持新的go命令-asan选项。

因为编译器的类型检查器被完全替换以支持泛型,一些错误消息现在可能使用与以前不同的措辞。在某些情况下,Go 1.18 之前的错误消息提供了更多详细信息,或者以更有用的方式表述。我们打算在 Go 1.19 中解决这些情况。

由于与支持泛型相关的编译器的更改,Go 1.18 的编译速度可能比 Go 1.17 的编译速度慢大约 15%。编译代码的执行时间不受影响。我们打算在未来的版本中提高编译器的速度。

Linker (应该和汇编有关,没用到过)

链接器发出的重定位要少得多。因此,大多数代码库将链接得更快,链接所需的内存更少,并生成更小的二进制文件。处理 Go 二进制文件的工具应该使用 Go 1.18 的debug/gosym包来透明地处理新旧二进制文件。

新的-asan链接器选项支持新的go命令-asan选项。

引导程序

从源代码构建 Go 版本GOROOT_BOOTSTRAP 且未设置时,Go 的早期版本会在目录中查找 Go 1.4 或更高版本的引导工具链HOME/go1.4(%HOMEDRIVE%%HOMEPATH%go1.4在 Windows 上)。Go 现在首先查找HOME/go1.17或HOME/sdk/go1.17 在回退到 之前查找HOME/go1.4。我们打算让 Go 1.19 要求 Go 1.17 或更高版本进行引导,并且此更改应该使过渡更顺畅。有关更多详细信息,请参阅go.dev/issue/44505。

核心库

新debug/buildinfo包装

新debug/buildinfo包提供对模块版本、版本控制信息和嵌入在go命令构建的可执行文件中的构建标志的访问。runtime/debug.ReadBuildInfo 通过当前运行的二进制文件和go version -m命令行 也可以获得相同的信息 。

新net/netip包装 (直接去看源码)

新net/netip 包定义了一个新的 IP 地址类型,Addr. 与现有 net.IP类型相比,该netip.Addr类型占用的内存更少,不可变,并且具有可比性,因此它支持== 并可以用作映射键。

除了Addr,包还定义了 AddrPort,表示 IP 和端口,以及 Prefix,表示网络 CIDR 前缀。

该包还定义了几个函数来创建和检查这些新类型: AddrFrom4, AddrFrom16, AddrFromSlice, AddrPortFrom, IPv4Unspecified, IPv6LinkLocalAllNodes, IPv6Unspecified, MustParseAddr, MustParseAddrPort, MustParsePrefix, ParseAddr, ParseAddrPort, ParsePrefix, PrefixFrom.

该net包包括与现有方法并行的新方法,但返回netip.AddrPort而不是较重的net.IP或 *net.UDPAddr类型: Resolver.LookupNetIP, UDPConn.ReadFromUDPAddrPort, UDPConn.ReadMsgUDPAddrPort, UDPConn.WriteToUDPAddrPort, UDPConn.WriteMsgUDPAddrPort。新UDPConn方法支持免分配 I/O。

该包现在还包括在现有/ 类型和: , , , net之间进行转换的函数和方法 。 TCPAddrUDPAddrnetip.AddrPortTCPAddrFromAddrPortUDPAddrFromAddrPortTCPAddr.AddrPortUDPAddr.AddrPort

默认客户端禁用 TLS 1.0 和 1.1

如果Config.MinVersion 未设置,它现在默认为客户端连接的 TLS 1.2。任何安全最新的服务器都应该支持 TLS 1.2,并且自 2020 年以来浏览器就需要它。通过设置 Config.MinVersion为TLS 1.0 和 1.1 仍受支持VersionTLS10。服务器端默认值在 TLS 1.0 中保持不变。

GODEBUG=tls10default=1可以通过设置环境变量 将默认值暂时恢复为 TLS 1.0 。此选项将在 Go 1.19 中删除。

Rejecting SHA-1 certificates

crypto/x509现在将拒绝使用 SHA-1 哈希函数签名的证书。这不适用于自签名根证书。自 2017 年以来,已经证明了针对 SHA-1 的实际攻击, 并且自 2015 年以来,公众信任的证书颁发机构没有颁发 SHA-1 证书。

这可以通过设置 GODEBUG=x509sha1=1环境变量来临时恢复。此选项将在未来的版本中删除。

库的小改动

bufio (不太清楚作用,后面总结用法)

新Writer.AvailableBuffer 方法返回一个空缓冲区,其容量可能为非空,以便与类似追加的 API 一起使用。附加后,缓冲区可以提供给后续Write调用,并可能避免任何复制。

Reader.Reset和 方法现在 在Writer.Reset对带有 nil缓冲区的对象调用时使用默认缓冲区大小。

bytes

Cut()方法使用分隔符切割slice []byte, 它可以替代和简化许多常见用途 Index, IndexByte, IndexRune, and SplitN, Trim, TrimLeft, 和TrimRight 特别是对于小型 ASCII 割集,速度提高了 10 倍。

旧的 Title() 方法现在已经启用, 它不处理 Unicode 标点符号和特定语言的大写规则,并被 golang.org/x/text/cases 包取代。

crypto/elliptic (没用过)

P224、P384 和 P521 曲线实现现在都由 addchain 和 fiat-crypto 项目生成的代码支持,后者基于经过正式验证的算术运算模型。他们现在使用更安全的完整公式和内部 API。P-224 和 P-384 现在大约快四倍。所有特定的曲线实现现在都是恒定时间的。

对无效曲线点进行操作(方法返回 false 的那些点 IsOnCurve,并且从未被返回的Unmarshal或Curve在有效点上操作的方法)一直是未定义的行为,可能导致密钥恢复攻击,现在新后端不支持. P224如果向、P384或方法提供了无效点 P521,则该方法现在将返回一个随机点。在未来的版本中,该行为可能会更改为panic。

crypto/tls

新Conn.NetConn 方法允许访问底层 net.Conn.

crypto/x509 (针对特定系统的)

Certificate.Verify 现在使用平台 API 来验证 macOS 和 iOS 上的证书有效性,当使用 nil VerifyOpts.Roots 调用它或使用从 SystemCertPool 返回的pool.

SystemCertPool 现在可在 Windows 上使用。

在 Windows、macOS 和 iOS 上,当 CertPool返回的 aSystemCertPool 添加了额外的证书时, Certificate.Verify 将执行两种验证:一种使用平台验证器 API 和系统根,另一种使用 Go 验证器和附加根。平台验证者 API 返回的链将被优先考虑

CertPool.Subjects 已弃用。在 Windows、macOS 和 iOS 上, CertPool返回的 SystemCertPool 将返回一个池,该池不包括返回的切片中的系统根Subjects,因为静态列表无法恰当地表示平台策略,并且可能根本无法从平台 API 获得。

MD5WithRSAGo 1.19 中可能会删除 对使用依赖于 MD5 哈希 ( ) 的签名算法的签名证书的支持。

debug/dwarf

StructField 和BasicType 结构现在都有一个DataBitOffset字段,该字段保存属性的值( 如果DW_AT_data_bit_offset 存在)。

debug/elf

R_PPC64_RELATIVE 常量已添加 。

debug/plan9obj

如果文件没有符号部分,则 File.Symbols方法 现在返回新的导出错误值ErrNoSymbols 。

embed

go:embed 指令现在可以 以all:包含名称以点或下划线开头的文件开头。

go/ast

根据提案 添加 go/ast 和 go/token 以支持参数化函数和类型 ,对包进行了以下添加go/ast:

  • FuncType 和 TypeSpec 有一个新字段TypeParams来保存类型参数(如果有)
  • 新的表达式节点IndexListExpr 表示具有多个索引的索引表达式,用于具有多个显式类型参数的函数和类型实例化。

go/constant

新Kind.String 方法为接收者类型返回一个人类可读的名称。

go/token

新常量~添加到TILDE中用以支持泛型。

go/types

新Config.GoVersion 字段设置接受的 Go 语言版本。

为了支持泛型,这里添加了以下东西:

  • 添加了新类型 TypeParam、工厂函数 NewTypeParam和相关方法以表示类型参数。
  • 新类型 TypeParamList包含一个类型参数列表。
  • 新类型 TypeList包含一个类型列表。
  • 新的工厂函数 NewSignatureType分配一个 Signature带有(接收器或函数)类型的参数。要访问这些类型参数,该Signature类型有两个新方法 Signature.RecvTypeParams和 Signature.TypeParams.
  • Named类型有四种新方法: Named.Origin获取实例化类型的原始参数化类型, Named.TypeArgs获取 Named.TypeParams实例化或参数化类型的类型实参或类型参数,以及 Named.SetTypeParams设置类型参数(例如,在导入命名类型时由于可能的循环,命名类型和类型参数的设置不能同时进行)。
  • 该Interface类型有四个新方法: 查询接口定义的类型集的属性, Interface.IsComparable以及 设置和 测试接口是否是围绕类型约束字面量的隐式接口。 Interface.IsMethodSetInterface.MarkImplicitInterface.IsImplicit
  • 添加了新的类型 Unionand Term、工厂函数 NewUnion和 NewTerm、以及相关的方法来表示接口中的类型集。
  • 新函数 Instantiate 实例化了一个参数化类型。
  • 新Info.Instances 映射通过新类型记录函数和类型实例化 Instance。
  • 添加新类型ArgumentError 和相关方法以表示与类型参数相关的错误。
  • 添加了新的类型Context和工厂功能 NewContext ,以便通过新 Config.Context 字段在经过类型检查的包之间共享相同类型的实例。

谓词 AssignableTo, ConvertibleTo, Implements, Identical, IdenticalIgnoreTags, 和 AssertableTo 现在也适用于属于或包含通用接口的参数,即只能在 Go 代码中用作类型约束的接口。请注意,AssignableTo、 ConvertibleTo、Implements和 的行为AssertableTo未使用未实例化的泛型类型的参数定义,并且AssertableTo如果第一个参数是通用接口,则未定义。

html/template

在range管道内,新 {{break}}命令将提前结束循环,新{{continue}}命令将立即开始下一个循环迭代。

在第一个评估为假的参数之后停止评估参数

image/draw

当这些参数实现Go 1.17 中添加 的可选 和接口时, theDraw和DrawMaskfallback 实现(在参数不是最常见的图像类型时使用)现在更快 。draw.RGBA64Imageimage.RGBA64Image

net

net.Error.Temporary已被弃用。

net/http

Dial, DialContext, DialTLS, DialTLSContext字段在Transport 将正确使用, 来发出 HTTP 请求

新 Cookie.Valid 方法报告 cookie 是否有效。

新 MaxBytesHandler 函数创建 Handler包裹它的 ResponseWriterand 和 Request.Body。

在查找包含非 ASCII 字符的域名时,Unicode 到 ASCII 的转换现在按照 Unicode IDNA 兼容性处理标准 (UTS #46) 中定义的非过渡处理完成。改变了四种不同符文的解释:ß、ς、零宽度连接符 U 200D 和零宽度非连接符 U 200C。非过渡处理与大多数应用程序和 Web 浏览器一致。

os/user

User.GroupIds 现在当 cgo 不可用时使用 Go 原生实现。

reflect

新的 Value.SetIterKey 和Value.SetIterValue 方法使用映射迭代器作为源来设置一个值。它们等价于 Value.Set(iter.Key())and Value.Set(iter.Value()),但分配较少。

新 Value.UnsafePointer 方法将 Value 的值作为unsafe.Pointer. 这允许调用者从调用站点迁移Value.UnsafeAddr 并Value.Pointer 消除执行 uintptr 到 unsafe.Pointer 转换的需要(如 unsafe.Pointer 规则所要求的那样)。

新 MapIter.Reset 方法更改其接收器以迭代不同的地图。的使用 MapIter.Reset 允许在许多映射上进行无分配迭代。

添加了许多方法( Value.CanInt, Value.CanUint, Value.CanFloat, Value.CanComplex ) Value 来测试转换是否安全。

Value.FieldByIndexErr 已添加以避免在单 Value.FieldByIndex 步执行指向嵌入式结构的 nil 指针时发生的恐慌。

reflect.Ptr和 reflect.PtrTo 已分别重命名为 reflect.Pointer和 reflect.PointerTo,以与反射包的其余部分保持一致。旧名称将继续有效,但将在未来的 Go 版本中弃用。

regexp

regexp 现在将 UTF-8 字符串的每个无效字节视为U FFFD.

runtime/debug

该BuildInfo 结构有两个新字段,包含有关如何构建二进制文件的附加信息:

  • GoVersion 保存用于构建二进制文件的 Go 版本。
  • Settings 是一个 BuildSettings 结构切片,包含描述构建的键/值对。

runtime/pprof

CPU 分析器现在在 Linux 上使用每线程计时器。这增加了配置文件可以观察到的最大 CPU 使用率,并减少了某些形式的偏差。

strconv

strconv.Unquote 现在拒绝代理一般 (这个翻译有点问题,但是这个方法也没用到过)

strings

新方法Cut代替和简化 Index, IndexByte, IndexRune, and SplitN.

新方法Clone拷贝输入的string 返回的不是输入string的内存

Trim, TrimLeft, 和TrimRight 小型 ASCII 割集,速度提高了 10 倍。

Title 方法已弃用

sync

如果当前未持有锁, Mutex.TryLock, RWMutex.TryLock, RWMutex.TryRLock 将获取锁。

syscall

SyscallN 为 Windows 引入了 新函数,允许使用任意数量的参数进行调用。因此, Syscall, Syscall6, Syscall9, Syscall12, Syscall15, 和 Syscall18被弃用,取而代之的是SyscallN。

SysProcAttr.Pdeathsig 现在在 FreeBSD 中得到支持。

syscall/js

该Wrapper接口已被删除。

testing

-run 和 -bench 的参数中 / 的优先级已增加。 A/B|C/D 以前被视为 A/(B|C)/D,现在被视为 (A/B)|(C/D)。

如果 -run 选项未选择任何测试,则 -count 选项将被忽略。 这可能会在不太可能的情况下改变现有测试的行为,即测试更改了每次运行测试函数本身时运行的子测试集。

新testing.F类型由模糊测试使用。测试现在还支持命令行选项 -test.fuzz、-test.fuzztime 和 -test.fuzzminimizetime。

text/template

在range管道内,新 {{break}}命令将提前结束循环,新{{continue}}命令将立即开始下一个循环迭代。

and 函数不再总是计算所有参数; 它在第一个评估为假的参数之后停止评估参数。 同样, or 函数现在在第一个计算结果为 true 的参数之后停止计算参数。 如果任何参数是函数调用,这会有所不同。

text/template/parse

该包支持text/template and html/template {{break}}命令,同样通过新常量 NodeBreak 和新类型 BreakNode, 同样通过新常量 NodeContinue 和新类型 ContinueNode 支持新的 {{continue}} 命令。

unicode/utf8

新方法 AppendRune 添加 UTF-8字符的一个rune 到一个[]byte 中

0 人点赞