在Go中,似乎没有构造函数,但建议您使用函数分配 struct 类型的对象,例如,通常以"New"+TypeName命名

func NewRect(x,y, width, height float) *Rect {
     return &Rect(x,y,width, height)
}

然而,我不确定Go的内存布局.在C/C++中,这类代码意味着您返回一个指针,该指针指向一个临时对象,因为变量是在堆栈上分配的,并且在函数返回后,该变量可能是一些垃圾.在围棋中,我需要担心这样的事情吗?因为似乎没有标准表明在堆栈上分配什么样的数据,而在堆上分配什么样的数据.

就像在Java中一样,似乎有一个特别的点,即基本类型,如int,Float将被分配到堆栈上,其他从对象派生的对象将被分配到堆上.在围棋里,有没有关于这个的具体讨论?

推荐答案

Composite Literal section个提法是:

获取复合文字的地址(§地址运算符)会生成指向文字值实例的唯一指针.

That means the pointer returned by the New function will be a valid one (allocated on the stack).
Calls:

In a function call, the function value and arguments are evaluated in the usual order.
After they are evaluated, the parameters of the call are passed by value to the function and the called function begins execution.
The return parameters of the function are passed by value back to the calling function when the function returns.

你可以看到更多的in this answerthis thread.

正如"Stack vs heap allocation of structs in Go, and how they relate to garbage collection"中提到的:

值得注意的是,"栈"和"堆"这两个词没有出现在语言规范中的任何地方.


blog post "Escape Analysis in Go"个细节是发生了什么,mentioning the FAQ个:

如果可能,Go编译器将在函数的堆栈框架中为函数分配局部变量

这篇博文补充道:

执行"逸出分析"的代码位于100中.
从概念上讲,它try 确定局部变量是否脱离当前作用域;发生这种情况的只有两种情况,一种是返回变量的地址,另一种是将变量的地址分配给外部作用域中的变量.
如果变量转义,则必须将其分配到堆上;否则,将其放入堆栈是安全的.

有趣的是,这也适用于new(T)个分配.
如果它们不转义,它们最终将被分配到堆栈上.下面是一个澄清问题的例子:

var intPointerGlobal *int = nil

func Foo() *int {
    anInt0 := 0
    anInt1 := new(int)

    anInt2 := 42
    intPointerGlobal = &anInt2

    anInt3 := 5

    return &anInt3
}

Above, anInt0 and anInt1 do not escape, so they are allocated on the stack;
anInt2 and anInt3 escape, and are allocated on the heap.


另请参阅"Five things that make Go fast":

与C不同的是,C通过在函数范围内声明值,强制您 Select 值是存储在堆上、通过malloc存储在堆栈上,还是存储在堆栈上,而GO实现了一种称为转义分析的优化.

默认情况下,GO的优化始终处于启用状态.
您可以使用100switch 查看编译器的转义分析和内联决策.

因为转义分析是在编译时执行的,而不是在运行时执行的,所以无论垃圾收集器有多高效,堆栈分配总是比堆分配快.

Go相关问答推荐

T的Golang通用切片,其中 *T实现接口

语法-for循环中的initit陈述是否允许分配?

try 用GitHub操作中的release标签更新version. go文件,但失败了

[0]Func()as";请勿比较哨兵类型

如何使用Gorilla WebSockets实现Http.Hijacker&;alexedwards/scs/v2

使用一元或服务器流将切片从GRPC服务器返回到客户端

如何使用 AWS sdk 在 Go 中正确解组 PartiQL 查询的结果?

Golang Fiber Render - 将数据发送到多个布局

Golang 网络应用程序安全性:您是否应该判断输入是否为有效的 utf-8?

设置 graphql 的最大文件上传大小(golang)

创建新对象后如何返回嵌套实体?

Apache Beam 左加入 Go

使用 ssh 从私有 gilab 仓库导入一个 go 项目:未知修订

使用自定义处理程序 nats golang 保留订阅方法

grpc-gateway:重定向与定义不匹配(原始文件)

在我的情况下,如何以正确的方式测试方法?

GoLang 遍历 yaml 文件

httprouterhttp.HandlerFunc() 是如何工作的?

Golang:每个键具有多个值的映射

Golang 有类似 C++ 的 decltype 的东西吗?