一段奇怪代码引起的终极,请解惑
原文链接:遇到一段无法理解的代码,求解惑!
千言万语,最后归结为下面一段代码:
type pp struct {
arg any
}
func main() {
m := 1
l := 1
n := 1
foo(m)
fmt.Println(m, l, n)
println(m, l, n)
}
func foo(a any) {
println("foo", a, &a)
type S struct {
t unsafe.Pointer
data unsafe.Pointer
}
eval(a)
s := (*S)(unsafe.Pointer(&a))
*(*int)(s.data) = 10
}
func eval(a any) {
println(a, &a)
p := new(pp)
p.arg = a
}
现在的问题是:
- 函数
eval
中,p.arg
会导致 变量m
逃逸。为什么? - 在小于 255 的整数中,相同值的变量
l, n
,使用fmt.Println
打印时,会受到逃逸变量m
影响,变成 10,而使用println
打印时,m,l,n
三个变量的值仍然为 1。为什么? foo
函数中,接口类型变量a
通过结构体类型S
强制转换时,接口变量a
中,存储的两个指针(第一个指针表示接口中存储变量m
类型信息的内存地址,第二个指针表示接口中存储变量m
值的内存地址), 第一个指针赋给字段t
,第二个指针赋给字段data
。为什么?- 在main函数中,
m,l,n
三个变量的值相同,且均小于255的情况下,使用eval
函数时,代码如下:
func main() {
m := 1
l := 1
n := 1
eval(m)
eval(l)
eval(n)
}
那么在 eval
函数中,println(a),打印的值(都是指针)均相同。为什么?
提示:fmt 包中的 pp
结构体,也包含一个接口类型的 arg
字段。
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: