一段奇怪代码引起的终极,请解惑

原文链接:遇到一段无法理解的代码,求解惑!
千言万语,最后归结为下面一段代码:

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

}

现在的问题是:

  1. 函数 eval 中,p.arg 会导致 变量 m 逃逸。为什么?
  2. 在小于 255 的整数中,相同值的变量 l, n,使用 fmt.Println 打印时,会受到逃逸变量 m 影响,变成 10,而使用 println 打印时,m,l,n 三个变量的值仍然为 1。为什么?
  3. foo 函数中,接口类型变量 a 通过结构体类型 S 强制转换时,接口变量a 中,存储的两个指针(第一个指针表示接口中存储变量 m 类型信息的内存地址,第二个指针表示接口中存储变量m值的内存地址), 第一个指针赋给字段 t,第二个指针赋给字段 data。为什么?
  4. 在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 协议》,转载必须注明作者和本文链接
讨论数量: 7

那么多AI工具,就没想着问问看?

5天前 评论
KingSolvewer (楼主) 5天前
xbvan (作者) 5天前
KingSolvewer (楼主) 5天前
xbvan (作者) 5天前
KingSolvewer (楼主) 5天前

我愿意相信。

3天前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!