3 回答
TA贡献1878条经验 获得超4个赞
通常情况下,正在运行的 Go 程序无权访问编译该程序的文件系统目录。
嵌入功能在生成时对包源代码树中的文件进行抽取,并使这些文件在运行时可用。
包应嵌入包源代码树中包运行时需要访问的文件。
下面是一个示例:一个包 foo 具有源文件 foo.go。该软件包需要访问与 foo.go 位于同一目录中的文件 abc.txt。
如果当前工作目录是源代码目录,则包代码可以使用 os 访问文件。打开或任何调用 os 的东西。打开:
f, err := os.Open("abc.txt")
if err != nil {
// handle error
}
defer f.Close()
// do something with f
此代码可能会失败。运行时的当前工作目录不一定与包源代码目录相同。它通常不是同一个目录。包源目录甚至可能对正在运行的应用程序不可用。
在这种情况下,包应嵌入文件以确保包可以访问文件的内容:
//go:embed abc.txt
var abc []byte
TA贡献1828条经验 获得超13个赞
Embed 允许您将非 Go 文件视为源代码树的真正部分,而不是运行时依赖项。您可以将嵌入的文件视为源代码的扩展,并且可以类似地对待它们(主要是通过通常的源代码管理措施确保文件的内容)。
对于普通文件,即使它们在理论上是应用程序的静态元素,它们通常仍然需要每次运行程序时进行错误检查和验证,否则可能会出现无法解释的错误。使用嵌入式文件,一旦通过所有测试并部署应用程序,您就不必担心这一点。
嵌入文件的主要问题是,如果不重新生成程序,则无法更改内容,并且(可能很大)的文件大小会添加到二进制文件中。如果这不会造成问题,请继续。
任何时候,只要您可以合理地嵌入文件而不是在运行时加载它,这样做可能是可取的,因为它使程序部署更简单。
TA贡献1777条经验 获得超10个赞
为了添加其他答案,embed指令的一个缺点是不能使用它来嵌入操作系统级别的资源,例如Windows应用程序清单或Windows资源管理器中二进制文件旁边显示的图标;至少不是以操作系统会接受它的方式。
在Windows上,你可以使用像goversioninfo这样的东西来嵌入它们。
- 3 回答
- 0 关注
- 275 浏览
添加回答
举报