go嵌入文件报错

报错信息:
pattern resources/sql/*.sql: no matching files found

代码示例:
utils/embed_utils.go

//go:embed resources/sql
var embeddedFS embed.FS

func EmbedReadFile(path string) string {
data, err := embeddedFS.ReadFile(path)
if err != nil {
log.Println("embeddedFS.ReadFile error:", err)
return ""
}
return string(data)
}

官网嵌入文档:
https://pkg.go.dev/embed

原因分析

报错原因是将嵌入文件定义在了非 main 包下(如工具类文件中),导致编译器无法正确解析文件路径。

解决方案

  1. main 包中定义嵌入文件:
    • //go:embed 指令移至 main.go 文件中。
  2. 在工具类中注入嵌入文件系统:
    • 定义一个全局变量接收注入的 embed.FS
    • main 函数中调用注入方法。

修改后代码:

utils/embed_utils.go

package utils

import "embed"

// 定义全局变量接收注入的 FS
var embeddedFS embed.FS

// 注入 embed.FS 的方法
func InjectEmbeddedFS(fs embed.FS) {
embeddedFS = fs
}

// 读取嵌入文件
func EmbedReadFile(path string) string {
  data, err := embeddedFS.ReadFile(path)
  if err != nil {
    log.Println("embeddedFS.ReadFile error:", err)
    return ""
  }
  return string(data)
}

main.go

package main

import (
"embed"
"yourpackage/utils"
)

// 在 main 包中嵌入文件
//go:embed resources/sql
var embeddedFS embed.FS

func main() {
// 启动入口
utils.InjectEmbeddedFS(embeddedFS) // 注入 embed.FS
// ... 其他逻辑
}

注意事项

  1. 嵌入文件路径限制:
    //go:embed 指令只能访问当前包及其子目录下的文件,无法访问上级目录。
  2. 文件系统结构:
    • 嵌入的 FS 会保留原始目录结构,若需以指定目录为根,可使用 embed.FS.Sub("subdir") 创建子文件系统。
  3. 依赖注入必要性:
    将嵌入定义与使用分离,便于封装工具函数,同时符合代码解耦原则。

参考资料:

  • Go embed 官方文档
  • Go 嵌入文件最佳实践 (可选:可补充相关链接)