文章目录
在阅读golang源码时经常会遇到以//go:开头的注释,其目的就是告诉编译器如何编译这段代码。
//go:noescape
noescape的作用就是禁止逃逸,指定文件中的下一个声明必须是不带主题的func(意味着该声明的实现不是用Go编写的),不允许将作为参数传递的任何指针逃逸到堆或函数的返回值上。
runtime/os_dragonfly.go
//go:noescape
func lwp_create(param *lwpparams) int32
//go:noescape
func sigaltstack(new, old *stackt)
//go:noescape
func sigaction(sig uint32, new, old *sigactiont)
//go:nosplit
指定文件中声明的函数不得进行堆栈溢出检查,这是一个在不安全抢占调用goroutine时常用的做法。
runtime/chan.go
//go:nosplit
func chansend1(c *hchan, elem unsafe.Pointer) {
chansend(c, elem, true, getcallerpc())
}
//go:linkname localname [importpath.name]
使用[importpath.name]作为源代码中声明的localname的变量或函数。由于该指令可以破坏类型系统和包模块化。因此只有引用了 unsafe 包才可以使用。
举个例子,在time包中定义了runtimeNano的函数
time/time.go
//go:linkname r