embed

embed 作用和简单的使用

embed

embed是在Go 1.16中新加包。它通过//go:embed指令,可以在编译阶段将静态资源文件打包进编译好的程序中,并提供访问这些文件的能力。

作用

  • 部署过程更简单。传统部署要么需要将静态资源与已编译程序打包在一起上传,或者使用docker和dockerfile自动化前者,这在精神上是很麻烦的。
  • 确保程序的完整性。在运行过程中损坏或丢失静态资源通常会影响程序的正常运行。

embed的用法

基本语法非常简单,首先导入embed包,然后使用指令//go:embed 文件名 将对应的文件或目录结构导入到对应的变量上。
例如: 在当前目录下新建文件 version.txt,并输入内容 0.0.1

1
$echo 0.0.1 > version.txt

代码

可以使用如下代码将文件version.txt的内容嵌入到变量version中

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import (
_ "embed"
"fmt"
)

//go:embed version.txt
var version string

func main() {
fmt.Printf("version: %q\n", version)
}

运行

1
2
$ go run .
version: "0.0.1"

embed支持的类型

上面的示例是将文件内容嵌入了一共string类型的变量,还可以将文件内容嵌入到[]byte类型的变量,另外embed 包还提供了一种类型 embed.FS,下面在给一个embed.FS 类型变量的使用示例

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

//go:embed *.txt
var content embed.FS

func main() {
mutex := http.NewServeMux()
mutex.Handle("/", http.FileServer(http.FS(content)))
err := http.ListenAndServe(":8080", mutex)
if err != nil {
log.Fatal(err)
}
}

示例中将当前文件夹下的所有.txt文件都嵌入了变量 content中,并且在8080端口提供一共文件服务。

运行:

1
2
3
4
5
# 启动
$go run .
# 请求
$ curl 127.0.0.1:8080/version.txt
0.0.1

注意事项

  1. 在使用//go:embed指令的文件都需要导入 embed包。 例如,以下例子 没有导入embed包,即不会正常运行。
  2. //go:embed指令只能用在包一级的变量中,不能用在函数或方法级别。
  3. 当包含目录时,它不会包含以“.”或““开头的文件。但是如果使用通配符,比如dir/*,它将包含所有匹配的文件,即使它们以“.”或””开头。