defer调用存储的“列表” 完全是特定于实现的,因此您 没有可靠的方式访问此列表
。1,2个为*
G编译器家族中的实现细节(虽然有点老),可以发现在拉斯考克斯的研究博客。
延迟函数与当前goroutine(
g->Defer)和当前堆栈指针标识的(对于*
g系列)相关联。如果当前堆栈帧与存储在最顶部
Defer条目中的堆栈帧匹配,则调用此函数。
了解了这一点它 是 可以访问的使用CGO延迟功能列表。你得知道
- 当前的堆栈指针
- 函数的地址
- 当前的goroutine
但是,我不建议使用此功能。您描述的用例的一般解决方案是具有以下功能:
func setupRoutines() (setUp, tearDown func()) { // store db connection object and such return func() { }, func() { }}然后
tearDown,您可以在代码中共享该函数,该函数将使用调用
defer。这样,您仍然可以拥有所有数据库连接以及此类本地连接的好处,但是您可以共享初始化/断开连接功能。
小提琴玩
如果您真的想
unsafe和C 一起玩,可以将以下代码用作模板。
检查/运行时.c:
// +build gc#include <runtime.h>void ·FirstDeferred(void* foo) { foo = g->defer->fn; FLUSH(&foo);}inspect / inspect.go
package inspectimport "unsafe"func FirstDeferred() unsafe.Pointer
defer.go
package mainimport "defer/inspect"func f(a, b int) { println("deferred f(", a, b, ")")}func main() { defer f(1, 2) println( inspect.FirstDeferred() )}该代码(基于this)使您可以访问当前的go例程(
g),从而可以访问其
defer属性。因此,您应该能够访问该函数的指针并将其包装在go中
FuncVal并返回它。



