在站长的公众号里,看到了一篇关于 "Go 1.15 中,小整数转换为接口值时,将不再进行内存分配" 的文章。<br/>
原文地址:`https://mp.weixin.qq.com/s/1r0nt8nA3foDRRrbRp4omg`<br/><br/>
我自己闲得蛋疼,折腾了一下。代码运行后,为什么每一个打印出来的内存地址都会不一样?<br/>
OS: ubuntu server 18.04 LTS 64bit<br/>
go version: 1.15.2<br/>
我自己折腾的代码如下:<br/>
```go
package main
import "fmt"
func main() {
var slice = make([]interface{}, 3)
slice[0] = 1
slice[1] = 128
slice[2] = 256
for i := 0; i < 3; i++ {
fmt.Printf("%p, ", &slice[i])
}
println()
}
/*
运行结果:
0xc00005c150, 0xc00005c160, 0xc00005c170,
*/
```
<br/>
运行结果的截图:<br/>
![1.png](https://static.studygolang.com/200929/4ddf3bcb931fdaaf2ff674d234e78d2b.png)
<br/><br/>
按照 Go 1.15 开始的特性:小整数转换为 `interface{}` 将不再需要进行内存分配。<br/>
那为什么打印出来的 3 个地址都是不一样的?如果说 256 这个值打印出来的地址有变化,那是好理解的。但是 1 和 128,不都是在小整数范围内的,为什么它俩的内存地址不一样?<br/>
恳请大佬解惑,还是我哪里打开姿势不对?<br/>
**兄弟,我真是闲的跟你一样蛋疼……这东西真不好测试,为了获取到interface中的真实data地址,我也是头痛……**
**经过各种google,终于在万能的stackoverflow上看到一个好办法……**
附上stackoverflow地址:https://stackoverflow.com/questions/57696977/how-to-get-a-pointer-to-the-underlying-value-of-an-interface-in-go 。
附上wide的测试代码地址:https://wide.b3log.org/playground/49b4de79f363ef7c1415d2372f972344.go
#4
更多评论
你这里打印的是 slice 中元素的地址,都是连续的,看着没什么问题。至于`interface{}`,我就不清楚怎么查了,怀疑取值时go内部会转换掉,你很难拿到。要不一起看看 https://research.swtch.com/interfaces 研究下。
#1
我觉得吧, make只是分配一个interface{}的数组, 但是数组的值都是nil, 这个应该理解成void*, 这个地址有3个很正常, 指针本身也有地址的.你后来的赋值, 把小整数赋值过去, 不分配内存的意思我相信应该是这个小整数已经作为常量池的数据 固定在内存某个地方, 你的interface是直接指向这里的, 而不用另外新分配的动态变量地址.
#2