Go embed 静态文件嵌入
FreeGuideOnline
最新
2026-07-11
{{.Message}}
```代码示例:
package main
import (
"embed"
"html/template"
"log"
"net/http"
)
//go:embed data/templates/*
var templateFS embed.FS
func main() {
// 使用 ParseFS 一次性解析嵌入文件系统中的所有模板
tmpl, err := template.New("").ParseFS(templateFS, "data/templates/*.html")
if err != nil {
log.Fatal(err)
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
data := struct {
Title string
Message string
}{
Title: "Embed Demo",
Message: "模板嵌入成功!",
}
tmpl.ExecuteTemplate(w, "index.html", data)
})
log.Println("Server started on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
template.New("").ParseFS(templateFS, "data/templates/*.html")直接从embed.FS解析所有匹配的 HTML 模板。- 模板名称会自动去除路径前缀,保留文件名。因此执行时使用
index.html即可。
常用模式与最佳实践
条件编译与路径变量
一个常见的需求是为不同环境嵌入不同的配置文件。可以通过构建标签结合变量实现:
目录结构:
config/
config_dev.go
config_prod.go
main.go
config_dev.go:
//go:build dev
package main
import _ "embed"
//go:embed config_dev.json
var configJSON []byte
config_prod.go:
//go:build prod
package main
import _ "embed"
//go:embed config_prod.json
var configJSON []byte
main.go 中直接使用全局变量 configJSON。编译时指定标签即可切换:
- 开发环境:
go build -tags dev - 生产环境:
go build -tags prod
嵌入的注意事项
- 路径安全:
go:embed不允许使用..或绝对路径,只能引用当前模块内的子路径。 - 空目录不会被嵌入:即使目录存在,如果目录中没有 go:embed 匹配的文件,该目录不会被包含。
- 文件嵌入变量必须为包级别变量,局部变量不支持。
- 不可嵌入符号链接,若路径指向软链接,编译将报错。
- 文件变化不影响已编译的二进制。嵌入发生在编译期,运行时无法动态更新。若需要热更新,应考虑外部文件或引入额外的文件监听机制。
查看嵌入列表与调试
可以使用标准库 fs.WalkDir 遍历 embed.FS,打印所有可用的嵌入文件路径。这对于在开发阶段验证嵌入内容十分有用:
func printEmbedFiles(efs embed.FS) {
fs.WalkDir(efs, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
fmt.Println(path)
return nil
})
}