何时使用嵌入?

huangapple go评论79阅读模式
英文:

When to use embed?

问题

从Go 1.16开始,我们有了embed指令。它可以帮助我们将额外的文件(比如一个.txt文件)嵌入到可执行文件中,而无需额外提供该文件。(参考这里)。

我不太清楚什么被认为是“额外的文件”。所有不以.go结尾的文件都被认为是额外的文件吗?有没有例外?

我想将一个二进制的protobuf定义文件作为主要二进制文件的一部分进行发布,以便我的代码可以读取它。这个文件会被认为是额外的文件吗?还是它会成为主要二进制文件的一部分?

英文:

Starting Go 1.16, we have the embed directive. It helps us embed an extra file (say, a .txt file) into the executable without having to supply that file additionally. (Reference, here).

I don't quite follow what construes an 'extra file'. Are all files not ending in .go construed as extra files? Any exceptions?

I want to ship a binary protobuf definition file as a part of the main binary so that my code can read it. Would this file be an extra file? Or would it be a part of the main binary itself?

答案1

得分: 4

通常情况下,运行中的Go程序无法访问编译程序所在的文件系统目录。

嵌入功能会在构建时将包源代码树中的文件捆绑到运行时,使这些文件在运行时可用。

包应该从包源代码树中嵌入需要在运行时访问的文件。

以下是一个示例:包foo有一个名为foo.go的源文件。该包需要访问与foo.go相同目录中的abc.txt文件。

如果当前工作目录是源代码目录,则包代码可以使用os.Open或任何调用os.Open的方法访问该文件:

f, err := os.Open("abc.txt")
if err != nil {
    // 处理错误
}
defer f.Close()
// 使用f做一些操作

这段代码可能会失败。运行时的当前工作目录不一定与包源代码目录相同。它通常不是相同的目录。包源目录甚至可能对运行中的应用程序不可用。

在这种情况下,包应该嵌入该文件,以确保包可以访问文件的内容:

//go:embed abc.txt
var abc []byte
英文:

It is often the case that a running Go program does not have access to the file system directories from which the the program was compiled.

The embed feature slurps up files in the package source code tree at build time and makes those files available at runtime.

Packages should embed files from the package source code tree that the package needs to access at runtime.

Here's an example: A package foo has has the source file foo.go. The package needs to access the file abc.txt in the same directory as foo.go.

If the current working directory is the source code code directory, then the package code can access the file using os.Open or anything that calls os.Open:

  f, err := os.Open("abc.txt")
  if err != nil {
      // handle error
  }
  defer f.Close()
  // do something with f

This code can fail. The current working directory at runtime is not necessarily the same as the package source code directory. It usually is not the same directory. The package source directory may not even be available to the running application.

In this case, the package should embed the file to ensure that the package can access the contents of the file:

//go:embed abc.txt
var abc []byte

答案2

得分: 3

Embed允许您将非Go文件视为源代码树的真正部分,而不是运行时依赖。您可以将嵌入的文件视为源代码的扩展,并且可以类似地处理它们(主要是文件的内容由您通常的源代码控制措施保证)。

对于普通文件,即使它们在理论上是应用程序的静态元素,每次运行程序时仍然需要进行错误检查和验证,否则可能会出现莫名其妙的错误。使用嵌入文件,一旦通过了所有测试并部署了应用程序,您就不必再担心这个问题。

嵌入文件的主要问题是,您无法在不重新构建程序的情况下更改其内容,并且(可能很大的)文件大小会添加到二进制文件中。如果这不是问题,那就继续吧。

只要可以合理地嵌入文件而不是在运行时加载它,那么这样做可能是可取的,因为它简化了程序的部署。

英文:

Embed allows you to treat non-Go files as a true part of the source tree, rather than as a run-time dependency. You can see embedded files as an extension of your source code, and you can treat them similarly (mainly that the contents of the file are assured by your usual source control measures).

With normal files, even if they are in theory a static element of the application, they still generally require error checking and validation every time the program is run, or else inexplicable errors may ensue. With an embedded file, you don't have to worry about this once all tests are passed and you deploy the application.

The main issues of an embedded file are that you can't change the contents without rebuilding the program, and the (potentially large) file size gets added to the binary. If that doesn't pose a problem, go ahead.

Any time you can reasonably embed a file instead of loading it at run time, it is probably desirable to do so as it makes program deployment simpler.

答案3

得分: 0

除了其他答案之外,embed指令的一个缺点是无法用它来嵌入操作系统级资源,例如Windows应用程序清单或在Windows资源管理器中显示在二进制文件旁边的图标;至少不能以操作系统能够识别的方式来嵌入。

在Windows上,您可以使用类似goversioninfo的工具来嵌入这些资源。

英文:

To add to the other answers, one shortcoming of the embed directive is that you cannot use it to embed OS-level resources, such as Windows application manifests or an icon for display next to the binary in Windows Explorer; at least not in a way that the OS will pick up on it.

On Windows, you would use something like goversioninfo to embed those.

huangapple
  • 本文由 发表于 2021年6月17日 11:18:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/68012429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定