background
I believe some people like GO's original intention is:Cross-platform static compilation, if you do not use other libraries to reference CGO, the compiled executable binary files are generally very convenient to deploy. However, in practice, people have found that backend WEB programs developed using the Go language have static resources such as HTML templates, pictures, JS, CSS, JSON, etc. When deploying, these static resources need to be uploaded to the server with the binary program to be deployed. In today's current situation where containers are everywhere, in order to simplify the deployment process, can these static files be further packaged and deployed with the binary program? Wouldn't that be more convenient? For operation and maintenance, the benefit of packaging integration is the reduction of operation and maintenance complexity. For technical teams, packaging integration can also ensure program integrity and controllability.
Therefore, the GO community initiated a proposal that expects the Go compiler to support embedding static filesissue#35950. Now, this feature will be released with version 1.16, and the latest version is the Go 1.16 RC1 preview.
OK, next we will introduce the various functions of go embed in detail.
embed embed
└── cmd Test Directory ├── assets Static resource directory │ ├── . │ ├── │ └── └── testgoSource File
String, byte slice, file embed
package main import ( "embed" _ "embed" "fmt" ) //go:embed directive is used for embedding, and must be followed by the embedded variable name.//Only embedding as string, byte slice and three types, none of these three types alias (alias) and named types (such as type S string) are allowed.//Embed assets/ as string//go:embed assets/ var s string //The content of the file is embedded as slice of byte, that is, an array of bytes//go:embed assets/ var b []byte //Embed as a file system New file system FS//go:embed assets/ //go:embed assets/ var f func main() { ("embed string.", s) ("embed byte.", string(b)) data, _ := ("assets/") ("embed fs.", string(data)) data, _ = ("assets/") ("embed fs.", string(data)) }
After compiling and running, output:
embed string. hello golang!
embed byte. hello golang!
embed fs. hello golang!
embed fs. hello!
As can be seen from the above code, embed supports embedded as string, byte slice and these three types, and it is not allowed to be derived from these types.
Embed files
For FS type embedding, one variable can also be supported to embed multiple files.
//go:embed assets/ //go:embed assets/ var f
Of course, it is also supported, two variables are embedded in a file. Although the two variables are embedded in the same file, they are allocated independently when compiled and do not affect each other.
Embed folder
FS-type embedding supports folders. The separator uses forward slash/, which even Windows systems adopt this mode.
//go:embed assets var f func main() { data, _ := ("assets/") (string(data)) }
Embed Match
The go:embed directive can only write the folder name. In addition to the files and folders starting with . and _ in this folder, they will be embedded, and subfolders will be embedded recursively to form a file system for this folder.
If you want to embed files and folders starting with . and _, such as . files, you need to use *, such as go:embed assets/*.
It is not recursive, so the . and _ in the subfolder will not be embedded unless you are embedding specifically using subfolders:
├── assets │ ├── . │ ├── │ └── └── package main import ( "embed" _ "embed" "fmt" ) //go:embed assets/* var f func main() { data, _ := ("assets/.") (string(data)) }
FS file system
Implements the io/ interface, which can open a file and return:
package main import ( "embed" _ "embed" "fmt" ) //go:embed assets var f func main() { helloFile, _ := ("assets/") stat, _ := () ((), ()) }
It also provides ReadFileh and ReadDir functions to traverse file and folder information under a file:
package main import ( "embed" _ "embed" "fmt" ) //go:embed assets var f func main() { dirEntries, _ := ("assets") for _, de := range dirEntries { ((), ()) } }
Because it implements the io/ interface, it can return its subfolder as the new file system:
package main import ( "embed" _ "embed" "fmt" "io/fs" "io/ioutil" ) //go:embed assets var f func main() { as, _ := (f, "assets") hi, _ := ("") data, _ := (hi) (string(data)) }
Summarize:
- For individual files, embedding as strings and byte slices are supported
- Support embedding as new file systems for multiple files and folders
- The go:embed directive is used to embed, and must be followed by the embedded variable name.
- Only embedding into three types: string, byte slice and type derivation is not allowed.
The above is the detailed content of the implementation of the new Go 1.16 feature embed packaged static resource file. For more information about Go embed packaged static resources, please pay attention to my other related articles!