1 回答
TA贡献1836条经验 获得超4个赞
defer
存储调用的“列表”是完全特定于实现的,因此您没有可靠的方法来获取此列表。1 , 2 *g 编译器系列(虽然有点旧)的实现细节可以在 Russ Cox 的研究博客中找到。
延迟函数与当前的 goroutine ( g->Defer
)相关联,并且(在 *g 系列的情况下)由当前堆栈指针标识。如果当前堆栈帧与存储在最顶层Defer
条目中的堆栈帧匹配,则调用此函数。
有了这些知识,就可以使用 cgo 访问延迟函数列表。你得知道
当前堆栈指针
函数地址
当前的协程
但是,我不建议使用它。您所描述的用例的一般解决方案是具有这样的功能:
func setupRoutines() (setUp, tearDown func()) {
// store db connection object and such
return func() { /* connect db and such */ }, func() { /* close db and such */ }
}
在您的代码中,您可以共享该tearDown函数,该函数将使用defer. 这样,您仍然可以拥有所有数据库连接和本地连接,但您可以共享初始化/断开连接功能。
小提琴演奏
如果你真的有兴趣玩转unsafeC,你可以使用下面的代码作为模板。
检查/运行时.c:
// +build gc
#include <runtime.h>
void ·FirstDeferred(void* foo) {
foo = g->defer->fn;
FLUSH(&foo);
}
检查/检查.go
package inspect
import "unsafe"
func FirstDeferred() unsafe.Pointer
defer.go
package main
import "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并返回它。
- 1 回答
- 0 关注
- 181 浏览
添加回答
举报