Are you an LLM? You can read better optimized documentation at /src/technology/dateblog/2025/05/20250524-go-embed(允许将静态文件(如文本、二进制文件、目录等,直接嵌入到编译后的可执行程序中).md for this page in Markdown format
go:embed(允许将静态文件(如文本、二进制文件、目录等,直接嵌入到编译后的可执行程序中)
Go 语言的 go:embed 指令是在 Go 1.16 版本中引入的一项功能,允许将静态文件(如文本、二进制文件、目录等)直接嵌入到编译后的可执行程序中。这使得程序无需依赖外部文件即可运行,特别适合分发单文件应用或需要内置资源的场景(如 Web 服务器的静态资源)。
基本用法
需导入 embed 标准库,并通过 //go:embed 注释指令指定要嵌入的文件或目录。
支持的变量类型
string: 嵌入单个文本文件。[]byte: 嵌入单个二进制文件。embed.FS: 嵌入多个文件或目录(文件系统结构)。
示例代码
1. 嵌入单个文件
go
package main
import (
_ "embed"
"fmt"
)
//go:embed version.txt
var version string // 将 version.txt 的内容嵌入为字符串
func main() {
fmt.Println("Version:", version)
}1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
2. 嵌入二进制文件
go
//go:embed logo.png
var logoBytes []byte // 嵌入为字节切片1
2
2
3. 嵌入多个文件或目录
使用 embed.FS(文件系统)类型:
go
package main
import (
"embed"
"fmt"
)
//go:embed templates/*.html static/css/*
var content embed.FS // 嵌入 templates/ 下的 HTML 和 static/css/ 下的文件
func main() {
// 读取文件
data, _ := content.ReadFile("templates/index.html")
fmt.Println(string(data))
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
关键特性
路径规则:
- 路径是相对于
go:embed指令所在 Go 文件的目录。 - 支持通配符:
*匹配任意字符(非隐藏文件)。**匹配多级目录(需 Go 1.18+)。?匹配单个字符。- 示例:
//go:embed images/*.png data/**/*.json
- 路径是相对于
隐藏文件:
- 默认忽略以
.或_开头的文件/目录。 - 若需包含,需显式指定,如
//go:embed .config/*。
- 默认忽略以
权限保留:
- 嵌入的文件保留其原始权限(仅 Unix 系统生效)。
跨平台兼容性:
- 文件路径分隔符始终为
/(即使 Windows)。
- 文件路径分隔符始终为
使用示例
- Web 静态资源:将 HTML/CSS/JS 嵌入到 Go 二进制文件中。
go
package main
import (
"embed"
"github.com/gin-gonic/gin"
"io/fs"
"net/http"
)
//go:embed public/*
var embeddedFS embed.FS
func main() {
subFS, err := fs.Sub(embeddedFS, "public")
if err != nil {
panic("无法创建子文件系统: " + err.Error())
}
engine := gin.Default()
// 挂载嵌入的静态资源 即可通过 /static 访问静态资源 /static/index.html 等
engine.StaticFS("/static", http.FS(subFS))
engine.Run(":8080")
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- 配置文件:内置默认配置。
- 模板文件:无需运行时从磁盘加载。
注意事项
- 不可嵌入符号链接。
- 变量声明必须紧邻
//go:embed注释(中间不能有空行)。 - 仅支持包级变量,不能用于函数内的局部变量。
- 不支持绝对路径,所有路径均为相对路径。
与其他工具对比
- 优势:
- 官方支持,无需第三方库(如
go-bindata、pkger)。 - 语法简洁,无需生成额外代码。
- 官方支持,无需第三方库(如
- 劣势:
- 无法动态嵌入(所有文件需在编译时确定)。
总结
go:embed 提供了一种轻量且标准化的方式将静态文件嵌入 Go 程序,极大简化了资源管理。适合需要单文件分发或减少外部依赖的场景,是 Go 工具链的重要补充。