在以前,很多从其他语言转过来 Go 语言的同学会问到,或是踩到一个坑。就是以为 Go 语言所打包的二进制文件中会包含配置文件的联同编译和打包。
结果往往一把二进制文件挪来挪去,就无法把应用程序运行起来了。因为无法读取到静态文件的资源。
无法将静态资源编译打包进二进制文件的话,通常会有两种解决方法:
- 第一种是识别这类静态资源,是否需要跟着程序走。
- 第二种就是考虑将其打包进二进制文件中。
第二种情况的话,Go 以前是不支持的,大家就会去借助各种花式的开源库,例如:go-bindata/go-bindata 来实现。
但从在 Go1.16 起,Go 语言自身正式支持了该项特性,今天我们将通过这篇文章快速了解和学习这项特性。
基本使用
演示代码:
- import _ "embed"
- //go:embed hello.txt
- var s string
- func main() {
- print(s)
- }
我们首先在对应的目录下创建了 hello.txt 文件,并且写入文本内容 “吃煎鱼”。
在代码中编写了最为核心的 //go:embed hello.txt 注解。注解的格式很简单,就是 go:embed 指令声明,外加读取的内容的地址,可支持相对和绝对路径。
输出结果:
- 吃煎鱼
读取到静态文件中的内容后自动赋值给了变量 s,并且在主函数中成功输出。
而针对其他的基础类型,Go embed 也是支持的:
- //go:embed hello.txt
- var s string
- //go:embed hello.txt
- var b []byte
- //go:embed hello.txt
- var f embed.FS
- func main() {
- print(s)
- print(string(b))
- data, _ := f.ReadFile("hello.txt")
- print(string(data))
- }
输出结果:
- 吃煎鱼
- 吃煎鱼
- 吃煎鱼
我们同时在一个代码文件中进行了多个 embed 的注解声明。
并且针对 string、slice、byte、fs 等多种类型进行了打包,也不需要过多的处理,非常便利。