我是Go的新手,在C风格的基于堆栈的编程(其中自动变量位于堆栈上,分配的内存位于堆中)与Python风格的基于堆栈的编程(在其中唯一存在于堆栈中的东西是对堆上对象的引用/指针。

据我所知,以下两个函数给出的输出相同:

func myFunction() (*MyStructType, error) {
    var chunk *MyStructType = new(HeaderChunk)

    ...

    return chunk, nil
}


func myFunction() (*MyStructType, error) {
    var chunk MyStructType

    ...

    return &chunk, nil
}

即分配一个新的结构并返回它。

如果用C编写,第一个将对象放到堆上,第二个将对象放到堆栈上。第一个将返回指向堆的指针,第二个将返回指向堆栈的指针,该指针将在函数返回时消失,这将是一件坏事。

如果我用Python(或C#以外的许多其他现代语言)编写它,则示例2不可能实现。

我知道Go垃圾收集了两个值,因此上述两种形式都可以。

报价:

注意,与C语言不同,完全可以返回局部变量的地址。函数返回后,与变量关联的存储将保留。实际上,采用复合文字的地址会在每次对其求值时分配一个新实例,因此我们可以将后两行结合在一起。

但这引起了两个问题。

1-在示例1中,该结构在堆上声明。例子2呢?是在栈中声明的方式是否与在C中声明的方式相同,还是在堆上进行声明?

2-如果在堆栈上声明了示例2,则函数返回后如何保持可用状态?

3-如果实际上在堆上声明了示例2,那么如何通过值而不是通过引用传递结构?在这种情况下指针的意义是什么?