go1.23 新特性
go1.23 新特性
这里面主要记一些语法相关的变化,或者说是我更关注的地方的变化。
Linker
链接器现在不允许使用 //go:linkname 指令引用标准库(包括运行时)中未在定义中标记有 //go:linkname 的内部符号。同样,链接器不允许从汇编代码中引用此类符号。为了向后兼容,现有的 //go:linkname 用法仍然受到支持,这些用法在大型开源代码库中发现。但任何对标准库内部符号的新引用将被禁止。
链接器命令行标志 -checklinkname=0 可用于禁用此检查,适用于调试和实验用途。
当构建动态链接的 ELF 二进制文件(包括 PIE 二进制文件)时,新的 -bindnow 标志可以启用即时函数绑定。
简单来说就是说不允许直接 linkname 一些标准库符号,从下面的示例来看一下。
1 | package main |
go 1.13 之前代码是可以正常输出
1 | go run . |
尝试使用 go1.23 运行
1 | go run . |
可以看出程序已经无法正常运行
使用 -checklinkname=0 禁用此检查。
1 | go run -ldflags=-checklinkname=0 . |
至于禁用的原因是 “这种使用内部类型的情况是不可持续的”,是的一般这样就是要link一些内部的私有符号,而标准库将这些符号声明为私有的就是为了避免随意的访问,另外大量的访问就会使得私有符号有了公共符号的作用,使得内部的变更变得困难。
range-over-func
Go 1.23 将 (Go 1.22) 的“range-over-func”实验正式纳入语言中。现在,“for-range”循环中的“range”子句可以接受以下类型的迭代器函数作为 range 表达式:
func(func() bool)
func(func(K) bool)
func(func(K, V) bool)
这些类型的函数调用迭代器参数函数来生成“for-range”循环的迭代值。有关详细信息,请参阅 iter 包文档和语言规范。关于动机,参见 2022 年的“range-over-func”讨论。
这块主要是看下 这个 range-over-func 如何使用吧
先看个示例代码吧
1 | package main |
输出
1 | $ go run . |
理解有的晦涩,我写一下我对第二个循环的理解吧
1 | for { |
有的像其他语言的 forEach 循环, 首先 yield 的入参就是 range 返回的内容,而 for 大括号内的内容就是 yield 的方法体,continue 会变成 return true ,而 break 是 return false
其他变更和以上变更详细信息参见Go 1.23 Release Notes