昨天,也就是2021年2月18日,Go Team 发布了 Go1.16。
正如上面图中大家看到的,Go 1.16版本主要包括支持 macOS ARM64、工具链优化、运行时和库的实现优化等多项优化更新。并且,该版本保留了Go 1兼容性的承诺,几乎所有 Go 程序都能像以前一样继续编译和运行。
是不是已经跃跃欲试想要更新到最新版本?那咱们先看下如何更新:
一、更新Go版本到最新的1.16
如果你和我一样,用的是windows系统,那么可以通过下面的方式更新(如果是在国内记得配置 GOPROXY 后在更新,详细见 环境搭建和IDE推荐 ):
I:\My\golang\src\zkbhj>go get golang.org/dl/go1.16
go: downloading golang.org/dl v0.0.0-20210216195328-5eb6ea94c136
go: found golang.org/dl/go1.16 in golang.org/dl v0.0.0-20210216195328-5eb6ea94c136
I:\My\golang\src\zkbhj>go1.16 download
Downloaded 20.0% ( 15251 / 143940754 bytes) ...
Downloaded 67.6% ( 146311 / 143940754 bytes) ...
Downloaded 100.0% (143940754 / 143940754 bytes)
Unpacking C:\Users\Administrator\sdk\go1.16\go1.16.windows-amd64.zip ...
Success. You may now run 'go1.16'
I:\My\golang\src\zkbhj>go1.16 version
go version go1.16 windows/amd64
至此,你就可以在你的本地通过命令go1.16来体验最新版本啦。当然,你的命令go还是原来的版本,方便你在新老版本之间快速切换,如果程序在新版本下运行有问题的话。没有问题之后,就可以把go替换为go1.16即可。
另外,如果你是mac等类Linux平台上更新Go版本,操作基本上是一致的,命令如下图:
升级完最新版本,那就一起看看新版本有哪些新特性吧!
二、Go1.16版本新特性
该版本主要增加或优化了如下功能(列举了一些最常见的有用的改动,详细的可以打开官方的发行说明,链接见文末的参考地址):
- Ports
- Go 1.16 adds support of 64-bit ARM architecture on macOS (also known as Apple Silicon) 增加了对macOS 64ARM(Apple silicon)的支持(即苹果新发布的Apple芯片:M1)
- Go now supports the 64-bit ARM architecture on NetBSD 增加了对NetBSD 64ARM的支持
- Go now supports the MIPS64 architecture on OpenBSD (the openbsd/mips64 port). This port does not yet support cgo.增加了对OpenBSD MIPS64的支持,但还不支持cgo
- Go 1.16 drops support for x87 mode compilation (GO386=387) 放弃了对x87模式的支持
- Tools-Modules
- Module-aware mode is enabled by default.To switch to the previous behavior, set GO111MODULE to auto. GO111MODULE 环境变量现在默认为 on。可通过将 GO111MODULE 设置为 auto 切换回旧行为
- Build commands like go build and go test no longer modify go.mod and go.sum by default. 默认情况下编译命令执行时不再更改go.mod和go.sum文件
- go install now accepts arguments with version suffixes (for example, go install example.com/cmd@v1.0.0). go install命令现在支持增加版本参数
go install golang.org/x/tools/gopls@v0.6.5
// Remote-triggered crash in package foo. See CVE-2021-01234.
retract v1.0.5
//在此之后,已依赖 v1.0.5 的用户在检查更新或升级依赖包时将收到撤回通知。
//通知消息可能包括收回指令上方注释的文本
$ go list -m -u all
example.com/lib v1.0.0 (retracted)
$ go get .
go: warning: example.com/lib@v1.0.5: retracted by module author:
Remote-triggered crash in package foo. See CVE-2021-01234.
go: to switch to the latest unretracted version, run:
go get example.com/lib@latest
- The go command now supports including static files and file trees as part of the final executable, using the new //go:embed directive. 新增的 embed 包使用新的 //go:embed 指令,在编译时嵌入的文件,并对其进行访问。现在可以轻松地将支持数据文件捆绑到 Go 程序中,从而使使用 Go 进行开发更加顺畅。通过它,真正做到部署时只有一个二进制文件。
- The new io/fs package defines the fs.FS interface, an abstraction for read-only trees of files. The io/ioutil package has turned out to be a poorly defined and hard to understand collection of things. All functionality provided by the package has been moved to other packages. 一个新的io/fs 包定义了 fs.FS接口,一个文件只读树的抽象。然后不建议继续使用io/ioutil包了,相应的功能都陆续迁移到其他包(io和os)中。
三、Embed详细解读——让Go程序开发更加灵活顺畅
一句话描述://go:embed 指令允许在 Go 应用程序中包含任意文件和目录的内容。
使用 //go:embed 指令,需要导入 embed 包,嵌入单个文件,可以使用字符串类型的变量和字节类型切片的变量,并且可以使用 _ 空白导入 embed 包。FS 类型允许嵌入文件树,例如静态 Web 服务的文件目录,FS 实现了 io/fs 包的 FS 接口,因此,它可以与任何文件系统相关的包一起使用,包括 net/http,text\template,和 html\template。注意下面的写法:
import "embed"
//go:embed hello.txt
var s string
//go:embed hello.txt
var b []byte
//go:embed hello.txt
var f embed.FS
关于 //go:embed 指令,还有一些值得注意的细节,总结如下:
- //go:embed 指令可用于导出变量和未导出变量,具体取决于包是否希望将数据提供给其它包。
- //go:embed 指令只能在包作用域中与全局变量一起使用,而不能与局部变量一起使用
- FS 类型模式允许多个路径以空格分隔,字符串类型模式和字节类型的切片模式仅允许匹配单个文件路径
- 路径分隔符是正斜杠(即使在 Windows 系统中)
- 不能包含 . 或 .. 或空路径,也不能以斜杠开始或结束
- 如果要匹配当前目录中的所有内容,使用 * 而不是 .
FS 是只读值,因此, 可以安全地同时从多个 go 协程使用, 并且安全地将 FS 类型的值分配给对方。即是一个并发安全的值。FS 类型包含三个方法,分别是 Open,ReadDir 和 ReadFile。
- func (f FS) Open(name string) (fs.File, error) 打开要读取的命名文件,并作为 fs.File 返回它
- func (f FS) ReadDir(name string) ([]fs.DirEntry, error) 读取并返回整个命名目录
- func (f FS) ReadFile(name string) ([]byte, error) 读取并返回命名文件的内容
package main
import (
"embed"
"fmt"
)
//go:embed hello.txt
var f embed.FS
func main () {
bs, err := f.ReadFile("hello.txt")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(bs)
}
关于最新版本的Go 1.16就总结这么多,赶快去体验吧!
* 本页内容参考以下数据源:
- https://baijiahao.baidu.com/s?id=1691997221104562784
- release notes https://golang.org/doc/go1.16
- 文件读取包的ReadDir和DirEntry解读 https://mp.weixin.qq.com/s/fUizpO3brKPkd2dRrOJI0A
- Go1.16 的embed最佳实践 https://mp.weixin.qq.com/s/rE6txL9DDnh-MIZrh8FvLg
- 官方 modules 最佳指南 https://golang.org/doc/tutorial/create-module
- embed解读:https://mp.weixin.qq.com/s/AO0i9olKZlQ4gtxF3Gr1gA
- https://blog.golang.org/go116-module-changes