diff --git a/examples.txt b/examples.txt index d83f7f7..fa033a4 100644 --- a/examples.txt +++ b/examples.txt @@ -19,7 +19,8 @@ Strings and Runes Structs Methods Interfaces -Embedding +Struct Embedding +Embed Directive Generics Errors Goroutines diff --git a/examples/embed-directive/embed-directive.go b/examples/embed-directive/embed-directive.go new file mode 100644 index 0000000..964d4b0 --- /dev/null +++ b/examples/embed-directive/embed-directive.go @@ -0,0 +1,51 @@ +// Starting in Go version 1.16+, Go supports use of `//go:embed` +// which is a directive to embed files and folders into +// the application binary by the compiler. + +// Since Go does not have preprocessor or macros like C type of languages, +// `pragmas/directives` are implemented by the compiler as comments `//`. +// Using `//go:embed` tells the compiler to include arbitrary files/folders in binary. +package main + +// If you are not using any exported identifiers from `embed` package directly, +// you can add an underscore `_` before the package name, ask Go to import `embed` +// without directly using it, like this: `_ "embed"`. In this example, we remove the +// underscore as we need to use the `embed.FS` type from the package. +import ( + "embed" +) + +// Since one file is defined after the directive, the compiler will only include +// this single file, followed by variable `single_file_string` to access as `string` type. +//go:embed embed-directive.sh +var single_file_string string + +// Here is a similar example but include single file as `[]byte`. +// Note that `//go:embed` can only be used in package level, +// define it in any function will result in error. +//go:embed embed-directive.sh +var single_file_byte []byte + +// We can also embed multiple files or even folders with wildcard. +// Since Go resolves these files and folders during compile time, we have to use the files in +// current working directory as examples. In practice, you can embed files with `"//go:embed /path/to/folder"` +// or with another example `"//go:embed /path/to/folder/*"`. You can add multiple `//go:embed` before defining a variable. +//go:embed *.hash +//go:embed embed-directive.sh +var folder_FS embed.FS + +func main() { + + // Print out the content of `embed-directive.sh` as `string`. + println(single_file_string) + + // Print out the content of `embed-directive.sh` as `[]byte`. + println(string(single_file_byte)) + + // Print out the content of `embed-directive.hash` by reading the file from `folder_FS` first, + // then print out the content. + hash_file := "embed-directive.hash" + hash_content, _ := folder_FS.ReadFile(hash_file) + println(string(hash_content)) + +} diff --git a/examples/embed-directive/embed-directive.hash b/examples/embed-directive/embed-directive.hash new file mode 100644 index 0000000..6919f0c --- /dev/null +++ b/examples/embed-directive/embed-directive.hash @@ -0,0 +1,2 @@ +10914400b16498094a1a876856181673c3fcdfe0 +gk3Zh5Sx8rV diff --git a/examples/embed-directive/embed-directive.sh b/examples/embed-directive/embed-directive.sh new file mode 100644 index 0000000..ac19f3a --- /dev/null +++ b/examples/embed-directive/embed-directive.sh @@ -0,0 +1,4 @@ +# Use these commands to run the example +$ go run embed-directive.go + + diff --git a/examples/embedding/embedding.hash b/examples/embedding/embedding.hash deleted file mode 100644 index 4d55e33..0000000 --- a/examples/embedding/embedding.hash +++ /dev/null @@ -1,2 +0,0 @@ -316e334f61f03d59c8a45889a057903a786534ba -k5Z_CnP8DK9 diff --git a/examples/embedding/embedding.go b/examples/struct-embedding/struct-embedding.go similarity index 89% rename from examples/embedding/embedding.go rename to examples/struct-embedding/struct-embedding.go index 6bd021e..6f8efb0 100644 --- a/examples/embedding/embedding.go +++ b/examples/struct-embedding/struct-embedding.go @@ -1,5 +1,8 @@ // Go supports _embedding_ of structs and interfaces // to express a more seamless _composition_ of types. +// This is not to be confused with _go:embed_ which is +// a go directive introduced in go version 1.16 to embed +// files and folders into the application binary. package main diff --git a/examples/struct-embedding/struct-embedding.hash b/examples/struct-embedding/struct-embedding.hash new file mode 100644 index 0000000..cf11fd6 --- /dev/null +++ b/examples/struct-embedding/struct-embedding.hash @@ -0,0 +1,2 @@ +8ec60ccaf4c5803bd65a776e05b458b008ae52a7 +4B33kwDJ3fm diff --git a/examples/embedding/embedding.sh b/examples/struct-embedding/struct-embedding.sh similarity index 100% rename from examples/embedding/embedding.sh rename to examples/struct-embedding/struct-embedding.sh diff --git a/public/embed-directive b/public/embed-directive new file mode 100644 index 0000000..32703e9 --- /dev/null +++ b/public/embed-directive @@ -0,0 +1,222 @@ + + + + + Go by Example: Embed Directive + + + + +
+

Go by Example: Embed Directive

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Starting in Go version 1.16+, Go supports use of //go:embed +which is a directive to embed files and folders into +the application binary by the compiler.

+ +
+ + +
+

Since Go does not have preprocessor or macros like C type of languages, +pragmas/directives are implemented by the compiler as comments //. +Using //go:embed tells the compiler to include arbitrary files/folders in binary.

+ +
+ +
+package main
+
+
+

If you are not using any exported identifiers from embed package directly, +you can add an underscore _ before the package name, ask Go to import embed +without directly using it, like this: _ "embed". In this example, we remove the +underscore as we need to use the embed.FS type from the package.

+ +
+ +
+import (
+    "embed"
+)
+
+
+

Since one file is defined after the directive, the compiler will only include +this single file, followed by variable single_file_string to access as string type.

+ +
+ +
+//go:embed embed-directive.sh
+var single_file_string string
+
+
+

Here is a similar example but include single file as []byte. +Note that //go:embed can only be used in package level, +define it in any function will result in error.

+ +
+ +
+//go:embed embed-directive.sh
+var single_file_byte []byte
+
+
+

We can also embed multiple files or even folders with wildcard. +Since Go resolves these files and folders during compile time, we have to use the files in +current working directory as examples. In practice, you can embed files with "//go:embed /path/to/folder" +or with another example "//go:embed /path/to/folder/*". You can add multiple //go:embed before defining a variable.

+ +
+ +
+//go:embed *.hash
+//go:embed embed-directive.sh
+var folder_FS embed.FS
+
+
+ + + +
func main() {
+
+
+

Print out the content of embed-directive.sh as string.

+ +
+ +
+    println(single_file_string)
+
+
+

Print out the content of embed-directive.sh as []byte.

+ +
+ +
+    println(string(single_file_byte))
+
+
+

Print out the content of embed-directive.hash by reading the file from folder_FS first, +then print out the content.

+ +
+ +
+    hash_file := "embed-directive.hash"
+    hash_content, _ := folder_FS.ReadFile(hash_file)
+    println(string(hash_content))
+
+
+ + + +
}
+
+
+ + + + + + + + +
+

Use these commands to run the example

+ +
+ +
+$ go run embed-directive.go
+
+ + +

+ Next example: Generics. +

+ + + + +
+ + + + diff --git a/public/generics b/public/generics index bddca50..2cfe61d 100644 --- a/public/generics +++ b/public/generics @@ -9,7 +9,7 @@ onkeydown = (e) => { if (e.key == "ArrowLeft") { - window.location.href = 'embedding'; + window.location.href = 'embed-directive'; } diff --git a/public/index.html b/public/index.html index d4d2647..b26b680 100644 --- a/public/index.html +++ b/public/index.html @@ -69,7 +69,9 @@
  • Interfaces
  • -
  • Embedding
  • +
  • Struct Embedding
  • + +
  • Embed Directive
  • Generics
  • diff --git a/public/interfaces b/public/interfaces index 578bfab..a540baf 100644 --- a/public/interfaces +++ b/public/interfaces @@ -14,7 +14,7 @@ if (e.key == "ArrowRight") { - window.location.href = 'embedding'; + window.location.href = 'struct-embedding'; } } @@ -222,7 +222,7 @@ these structs as arguments to measure.

    - Next example: Embedding. + Next example: Struct Embedding.

    diff --git a/public/embedding b/public/struct-embedding similarity index 94% rename from public/embedding rename to public/struct-embedding index 8ca4b7f..90d034a 100644 --- a/public/embedding +++ b/public/struct-embedding @@ -2,7 +2,7 @@ - Go by Example: Embedding + Go by Example: Struct Embedding -
    -

    Go by Example: Embedding

    +
    +

    Go by Example: Struct Embedding

    @@ -230,7 +233,7 @@ we see that a container now implements the

    - Next example: Generics. + Next example: Embed Directive.

    Go supports embedding of structs and interfaces -to express a more seamless composition of types.

    +to express a more seamless composition of types. +This is not to be confused with go:embed which is +a go directive introduced in go version 1.16 to embed +files and folders into the application binary.

    @@ -42,7 +45,7 @@ to express a more seamless composition of types.

    - +
    package main