以标准库net/http
为例,DefaultClient定义为:
var DefaultClient = &Client{}
然而,DefaultServeMux被定义为:
var DefaultServeMux = &defaultServeMux
var defaultServeMux ServeMux
为一个对象定义两个变量有什么意义?它比简单的var DefaultServeMux = &ServeMux{}
有什么好处?
DefaultServeMux
部分是由Brad Fitzpatrick完成的优化. 我会复制并重新格式化他和Matthew Dempsky之间的对话从CL上的注释:
Matthew Dempsky:
确保我理解了,问题是做
var x = newFoo()
需要newFoo ()即使x未使用,也要调用
Brad Fitzpatrick:
是的,生成:
var x *T func init() { x = newFoo() }
链接器似乎从来没有删除过init块,即使它们只分配给那些只被读过的东西。因为也许newFoo也有副作用?
Matthew Dempsky:
与
var x = &y var y foo
跳过显式初始化代码。所以如果x没有被使用,它可以和所有类型foo的相关代码一起被消除吗?
Brad Fitzpatrick:
对
我检查了从最新源代码(commit 4f4a9c7fff)编译的go二进制文件的大小,我发现该提交的更改有很大帮助,但var DefaultServeMux = &ServeMux{}
稍微好一点。见下表:
实现 | 数据大小 |
---|---|
var DefaultServeMux = NewServeMux() | 15870476 |
var DefaultServeMux = &var defaultServeMux ServeMux | 15864704 (-5772) |
var DefaultServeMux = &ServeMux{} | 15864696 (-5780) |