go语言内置预编译 //go:embed xxx 使用详解

在go语言里面,我们可以使用一个"类注释"的语法来来让编译器帮助我们在编译的时候将一些文件或者目录读取到指定的变量中来供我们使用。

go:embed语法:

//go:embed****文件或者目录路径

var****变量名 变量类型

说明:

文件或者目录路径可以是相对路径,也可以是绝对路径,路径中可以使用通配符*来指定要加载的文件类型,这个的用法和 filepath.Glob(pattern string)函数的用法是一样的.

变量类型这里只支持2种变量类型 string 或者 embed.FS , 这个embed.FS是一个结构体,专门用来接收文件集合的,注意是只读文件集合

使用示例

在下面的示例中我们定义了2个全局变量: MyAbc用来接收abc.txt中的内容; MyStaticFs用来接收statics文件夹下的html文件信息。 在 fs_test.go文件中,我们演示了如何使用我们定义的预编译变量,和如何将 embed.FS类型转换为 http.FileSystem 以及创建一个简单的静态服务示例。

假设我们的文件目录结构如下

bash 复制代码
├── abc.txt
├── fs.go
├── main.go
└── statics
    └── index.html

abc.txt 的文件内容

html 复制代码
abc123

fs.go 这个是我们的**//go:embed的预编译定义**

Go 复制代码
package main

import (
	"embed"
)

//go:embed abc.txt
var MyAbc string

//go:embed statics/*.html
var MyStaticFs embed.FS

fs_test.go使用示例

Go 复制代码
package main

import (
	"fmt"
	"net/http"
	"testing"
)

func TestDemo(t *testing.T) {
	abc := MyAbc
	// 使用预编译的变量
	fmt.Println("预编译变量MyAbc的内容为:", abc) // abc123

	// 这里我们就可以直接使用我们定义的预编译变量了, 他的类型是 embed.FS
	statics := MyStaticFs

	// 创建一个静态文件服务的handler  注意这里使用的是FileServerFS
	// handler := http.FileServerFS(statics)

	// 如果要是哟共 FileServer 则需要将类型embed.FS转换为http.FileSystem
	staticsFs := http.FS(statics)
	handler := http.FileServer(staticsFs)

	http.ListenAndServe(":8000", handler)
}

运行内存图解和总结

通过上面的图示,我们可以看到,编译器将文件abc.txt的内容读取并赋值给了我们定义的变量MyAbc, 将文件夹 statics 中的html文件和文件夹自己放入到了我们定义的 embed.FS 类型变量 MyStaticFs里面, 在这个变量里面包含了我们定义的文件的名称完整内容和文件hash等信息,可见go是吧我们指定的文件夹下面的所有文件内容都读取到了FS变量里面了,所以这个地方建议只放小文件,大文件千万别用这种模式来操作!!!

embed.FS只读文件集合结构体定义参考:

这个里面详情阐述了FS结构体的用法和 文件模式的用法。

Go 复制代码
// An FS is a read-only collection of files, usually initialized with a //go:embed directive.
// When declared without a //go:embed directive, an FS is an empty file system.
//
// An FS is a read-only value, so it is safe to use from multiple goroutines
// simultaneously and also safe to assign values of type FS to each other.
//
// FS implements fs.FS, so it can be used with any package that understands
// file system interfaces, including net/http, text/template, and html/template.
//
// See the package documentation for more details about initializing an FS.
type FS struct {
	// The compiler knows the layout of this struct.
	// See cmd/compile/internal/staticdata's WriteEmbed.
	//
	// The files list is sorted by name but not by simple string comparison.
	// Instead, each file's name takes the form "dir/elem" or "dir/elem/".
	// The optional trailing slash indicates that the file is itself a directory.
	// The files list is sorted first by dir (if dir is missing, it is taken to be ".")
	// and then by base, so this list of files:
	//
	//	p
	//	q/
	//	q/r
	//	q/s/
	//	q/s/t
	//	q/s/u
	//	q/v
	//	w
	//
	// is actually sorted as:
	//
	//	p       # dir=.    elem=p
	//	q/      # dir=.    elem=q
	//	w/      # dir=.    elem=w
	//	q/r     # dir=q    elem=r
	//	q/s/    # dir=q    elem=s
	//	q/v     # dir=q    elem=v
	//	q/s/t   # dir=q/s  elem=t
	//	q/s/u   # dir=q/s  elem=u
	//
	// This order brings directory contents together in contiguous sections
	// of the list, allowing a directory read to use binary search to find
	// the relevant sequence of entries.
	files *[]file
}
相关推荐
明月看潮生12 分钟前
青少年编程与数学 02-003 Go语言网络编程 15课题、Go语言URL编程
开发语言·网络·青少年编程·golang·编程与数学
明月看潮生17 分钟前
青少年编程与数学 02-003 Go语言网络编程 14课题、Go语言Udp编程
青少年编程·golang·网络编程·编程与数学
南宫理的日知录22 分钟前
99、Python并发编程:多线程的问题、临界资源以及同步机制
开发语言·python·学习·编程学习
逊嘘39 分钟前
【Java语言】抽象类与接口
java·开发语言·jvm
Half-up42 分钟前
C语言心型代码解析
c语言·开发语言
Source.Liu1 小时前
【用Rust写CAD】第二章 第四节 函数
开发语言·rust
monkey_meng1 小时前
【Rust中的迭代器】
开发语言·后端·rust
余衫马1 小时前
Rust-Trait 特征编程
开发语言·后端·rust
monkey_meng1 小时前
【Rust中多线程同步机制】
开发语言·redis·后端·rust
Jacob程序员1 小时前
java导出word文件(手绘)
java·开发语言·word