go:build
go:embed
在embed中,可以将静态资源文件嵌入到三种类型的变量,分别为:字符串、字节数组、embed.FS文件类型
如:main.go
package main
import (
"embed"
"fmt"
)
//go:embed testdata.txt
var s string
//go:embed testdata.txt
var b []byte
//go:embed *.txt
var f embed.FS
func main() {
fmt.Println(s)
fmt.Println(b)
fmt.Println(f.ReadFile("testdata.txt"))
}
testdata.txt内容为
中国
人民
上面代码的执行结果为:
中国
人民
[228 184 173 229 155 189 10 228 186 186 230 176 145]
[228 184 173 229 155 189 10 228 186 186 230 176 145] <nil>
go:generate
作用:
go generate 允许你在 go 代码中来运行当前系统中已安装的程序,原则上你可以运行任何程序,但是此命令设计的初衷是用来创建或者更新go源码文件。
必须手动执行 go generate,才会去解析执行 generate 指令,并且 go generate 命令不会执行go源代码。
单个运行只需要在对应目录(包)下执行:go generate
注意事项:
- 必须在.go源码文件中。
- 每个源码文件可以包含多个generate特殊注释。
- 显示运行go generate命令时,才会执行特殊注释后面的命令。
- 如果前面的注释执行出错,则终止执行。
- //与go:generate之间不能有空格。
可以通过执行go generate来解析执行代码里的generate指令.
go:linkname
internal包下的方法在外部包无法使用,当需要使用一个外部包未导出的方法时可以使用该编译器指令;
将当前声明的方法的具体实现绑定到一个外部包未导出的方法上;
使用时需要导入unsafe包
注意: linkname 是双向的,具有导出 和导入 两种使用方式。
导出的不能被作为导入,但是导入的可以作为多个导入, 仅限函数,变量不行
//go:nosplit
跳过栈溢出检测。
什么是栈溢出?
一个 Goroutine 的起始栈大小是有限制的,且比较小的,才可以做到支持并发很多 Goroutine,并高效调度。
stack.go 源码中可以看到,_StackMin 是 2048 字节,也就是 2k,它不是一成不变的,当不够用时,它会动态地增长。
那么,必然有一个检测的机制,来保证可以及时地知道栈不够用了,然后再去增长。
回到话题,nosplit 就是将这个跳过这个机制。显然地,不执行栈溢出检查,可以提高性能,但同时也有可能发生 stack overflow 而导致编译失败。
//go:noescape
禁止逃逸。
注意:
它必须指示一个只有声明没有主体的函数
//go:norace
跳过竞态检测,减少编译时间;
//go:notinheap
//go:yeswritebarrierrec
//go:nowritebarrierrec
·