作者:陈明勇
个人网站:https://chenmingyong.cn
文章持续更新,如果本文能让您有所收获,欢迎点赞收藏加关注本号。 微信阅读可搜《程序员陈明勇》。 这篇文章已被收录于 GitHub https://github.com/chenmingyong0423/blog,欢迎大 家Star 催更并持续关注。
前言
Go 1.23
版本在北京时间 2024 年 8 月 14 日凌晨 1:03 发布。该版本带来了多项重大更新,具体内容可以参考我之前的文章:Go 1.23 版本发布啦,这些重大更新你一定要知道!。本文将重点介绍 slices
、sync
等核心库的小改进。
准备好了吗?准备一杯你最喜欢的咖啡或茶,随着本文一探究竟吧。
slices
slices
库新增了一个 Repeat
函数,该函数返回一个新切片,该切片是将原始切片重复指定次数后的结果。
Repeat
函数的函数签名为 Repeat[S ~[]E, E any](x S, count int) S
,其中:
S
是切片类型,即~[]E
,表示任意元素类型E
组成的切片。E
是切片中的元素类型,any
表示可以是任何类型。x S
是传入的原始切片,类型为S
。count int
是指定重复的次数,即原始切片x
将会被重复count
次。- 返回值类型
S
是新的切片,包含了原始切片重复后的结果。
代码示例
package main
import (
"fmt"
"slices"
)
func main() {
s := []string{"程序员", "陈明勇"}
repeat := slices.Repeat(s, 2)
fmt.Println(repeat)
}
程序运行结果:
[程序员 陈明勇 程序员 陈明勇]
需要注意的是当指定的参数 count
为负数或新切片长度 len(x) * count
溢出时,将会发生 panic
。
sync
你是否还记得 Go 1.21
新增的几个内置函数?其中就包括 clear
,该内置函数用于清空变量类型为 slice
或 map
的变量中的元素,但它不支持对 sync.Map
进行操作。
为了支持清空操作,在 Go 1.23
版本的 sync
库中,新增了 Map.Clear
方法。这个方法用于删除所有元素,使 Map
变为空。它类似于 clear
方法。
代码示例
package main
import (
"fmt"
"sync"
)
func main() {
mp := &sync.Map{}
mp.Store("name", "陈明勇")
mp.Store("age", 18)
fmt.Println(mp.Load("name"))
fmt.Println(mp.Load("age"))
mp.Clear()
fmt.Println(mp.Load("name"))
fmt.Println(mp.Load("age"))
}
程序运行结果:
陈明勇 true
18 true
<nil> false
<nil> false
实际上,Clear
方法内部也是通过调用 clear
函数来清空 sync.Map
结构体中维护的底层 map
对象。
panic
在 Go 1.23
版本中,程序发生 panic
后打印的回溯信息里,错误信息的第二行以及后续行将会缩进一个制表符,以便能够明确区分这些行与第一个 goroutine
的堆栈跟踪。
我们来看看在不同版本中的 panic
信息打印对比:
示例代码
package main
func main() {
panic("程序员\n陈\n明\n勇")
}
在 Go 1.23
之前的版本中的运行结果:
panic: 程序员
陈
明
勇
goroutine 1 [running]:
main.main()
main.main()
/chenmingyong/godemo/main.go:4 +0x25
在 Go 1.23
版本中的运行结果:
panic: 程序员
陈
明
勇
goroutine 1 [running]:
main.main()
/chenmingyong/godemo/main.go:4 +0x25
os
os
库新增了一个 CopyFS
函数,用于将 fsys.FS
安全地复制到本地文件系统
CopyFS
函数的函数签名为 func CopyFS(dir string, fsys fs.FS) error
,其中:
dir
是目标目录的路径。如果这个目录不存在,CopyFS
会自动创建它。fsys
是要复制的文件系统,为fs.FS
接口的一个实例。
代码示例
package main
import (
"os"
)
func main() {
fs := os.DirFS("/Users/chenmingyong/workspace/temp")
err := os.CopyFS("/Users/chenmingyong/workspace/temp2", fs)
if err != nil {
panic(err)
}
}
在上述代码示例中,使用 os.DirFS
函数将 /Users/chenmingyong/workspace/temp
目录表示为一个 fs.FS
对象,然后通过 os.CopyFS
函数将该目录下的所有目录和文件复制到指定目录里。
需要注意的是 CopyFS
不会覆盖目标目录中已有的文件。如果 fsys
中的某个文件在目标目录中已经存在,函数会返回一个错误。
有了 CopyFS
函数,当我们需要将一个目录里的 文件和子目录 复制到另一个目录时,我们不再需要自定义代码实现这个功能。
path/filepath
path/filepath
库新增了一个 Localize
函数,该函数主要用于将以斜杠 /
分隔的路径转换为操作系统特定的路径格式。
代码示例:转 Windows 路径
package main
import (
"fmt"
"path/filepath"
)
func main() {
unixPath := "chenmingyong/file.txt" // Unix 风格的路径
localizedPath, err := filepath.Localize(unixPath)
if err != nil {
panic(err)
}
fmt.Printf("本地化后的路径: %s\n", localizedPath)
illegalPath := "C:\\Users\\chenmingyong\\Desktop\\file.txt" // 非法路径
_, err = filepath.Localize(illegalPath)
if err != nil {
fmt.Printf("错误信息: %s\n", err)
}
}
程序运行结果:
本地化后的路径: chenmingyong\file.txt
错误信息: invalid path
Localize
函数内部会通过 io/fs.ValidPath
来校验路径的合法性,路径中不能包含任何无效字符或格式,否则会返回 error
。比如在 Windows
系统上路径中包含 \
作为文件名的一部分,函数会返回一个错误。
小结
本文主要介绍了 Go 1.23
版本中 slices
和 sync
等核心库的新增特性及其用法。整体而言,这些改进和新增功能大大提升了开发者在使用 Go
语言进行开发时的体验和效率。