function - 在 Golang 中返回函数时的内存分配是多少?
问题描述
这是一个简化的代码
func MyHandler(a int) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteCode(a)
})
}
每当一个 http 请求到来时,MyHandler 都会被调用,它会返回一个用于处理请求的函数。因此,每当一个 http 请求到来时,都会创建一个新的函数对象。函数被视为 Go 中的第一类。我试图了解从内存的角度返回函数时实际发生的情况。当您返回一个值时,例如一个整数,它将占用堆栈中的 4 个字节。那么如何在函数体内返回一个函数和很多东西呢?这是一种有效的方法吗?有什么缺点?
解决方案
如果你不习惯闭包,它们可能看起来有点神奇。但是,它们很容易在编译器中实现:
编译器查找必须由闭包捕获的任何变量。它将它们放入一个工作区,只要闭包本身存在,该工作区就会被分配并保持分配状态。
然后编译器生成带有秘密额外参数的内部函数,或一些其他运行时技巧,1以便调用该函数激活闭包。
因为返回的函数通过编译时安排访问其闭包变量,所以没有什么特别需要的。由于 Go 是一种垃圾收集语言,因此也不需要其他任何东西:指向闭包的指针使闭包数据保持活动状态,直到指针消失,因为无法再调用函数,此时闭包数据消失(嗯,在下一次 GC 时)。
1 GCC 有时使用trampolines为 C 执行此操作,其中 trampolines 是在运行时生成的可执行代码。可执行代码可以设置寄存器或传递额外参数等。这可能会很昂贵,因为在运行时被视为数据的东西(生成的代码)必须在运行时转换为可执行代码(可能需要系统调用并可能需要一些监督代码“审查”生成的运行时代码)。
Go不需要任何这些,因为该语言在定义时考虑到了闭包,因此实现者不会,呃,“关闭”任何简单的方法来使这一切工作。一些运行时 ABI 的定义也考虑到了闭包,例如,r1
在所有指向函数的指针类型中,寄存器被保留为闭包变量指针,或者一些类似的类型。
推荐阅读
- c# - 如何使用 asp.net 在动态 crm 中创建帐户?
- ios - 从同名的 xcasset 访问音频和图像
- go - Build error using golang race detector
- sql-server - 分析条形图的表列 - PowerBI 中的 SQL Server
- r - 任何人都可以帮我改变r中的迄今为止的因素吗?
- neo4j - How to use MERGE to create or reuse a part of pattern?
- javascript - Div 容器不采用百分比的屏幕大小
- eyeshot - 将曲面缝合到 Solid3D
- haskell - 范围类型变量代表类型变量而不是类型的意义
- c# - 以编程方式加载程序集及其依赖项时的奇怪行为