我需要defer使用C库来释放手动创建的分配,但我也需要os.Exit在某些时候使用非 0 状态。棘手的部分是os.Exit跳过任何延迟指令:
defer
C
os.Exit
package main import "fmt" import "os" func main() { // `defer`s will _not_ be run when using `os.Exit`, so // this `fmt.Println` will never be called. defer fmt.Println("!") // sometimes ones might use defer to do critical operations // like close a database, remove a lock or free memory // Exit with status code. os.Exit(3) }
只需将您的程序向下移动一个级别并返回您的退出代码:
package main import "fmt" import "os" func doTheStuff() int { defer fmt.Println("!") return 3 } func main() { os.Exit(doTheStuff()) }
runtime.Goexit() 是实现这一目标的简单方法。
runtime.Goexit()
Goexit 终止调用它的 goroutine。没有其他 goroutine 受到影响。Goexit 在终止 goroutine 之前运行所有延迟调用。然而,因为 Goexit 并不恐慌,这些延迟函数中的任何恢复调用都将返回 nil。
然而:
从主协程调用 Goexit 会终止该协程,而不会返回 func main。由于 func main 没有返回,程序继续执行其他 goroutine。如果所有其他 goroutine 退出,程序就会崩溃。
所以如果你从主goroutine调用它,main你需要在顶部添加
main
defer os.Exit(0)
在此之下,您可能想要添加一些其他defer语句,以通知其他 goroutine 停止和清理。