英文:
Understanding memory allocation for named returned type
问题
在下面的代码示例中,我可以假设我不需要分配返回的值吗?编译器会始终分配任何函数的命名返回值吗?
package main
import "fmt"
type Point struct {
X, Y int
}
func MakePoint(x, y int) (pt Point) {
pt.X = x
pt.Y = y
return
}
func main() {
fmt.Printf("%v\n", MakePoint(1, 2))
}
另外,为什么我需要在函数末尾添加return
语句?这是编译器的一个错误吗?
如果我决定返回一个指针:
func MakePoint(x, y int) (pt *Point) {
代码会编译通过,但我会得到一个运行时错误!为什么编译器让我相信不需要使用pt = new(Point)
这样的语句进行分配?这是编译器的另一个错误吗?显然,我在Go语言中对内存分配有一些重要的东西没有理解。
英文:
In the following code sample, can I assume that I don't need to allocate the returned value? Will the compiler always allocate any function's named returned value?
package main
import "fmt"
type Point struct {
X, Y int
}
func MakePoint(x, y int) (pt Point) {
pt.X = x
pt.Y = y
return
}
func main() {
fmt.Printf("%v\n", MakePoint(1, 2))
}
Also, why do I need to add the return
statement at the end of the function? Is this a bug with the compiler?
If I decide to return a pointer:
func MakePoint(x, y int) (pt *Point) {
The code will compile but I am getting a runtime error! Why is the compiler letting me believe an allocation with a statement such as pt = new(Point)
is not needed? Is this another bug with the compiler? Clearly, I am missing something crucial about memory allocation in Go.
答案1
得分: 1
编译器总是会为任何函数的命名返回值分配内存。
此外,为什么我需要在函数末尾添加返回语句?这是编译器的一个错误吗?
因为返回一个值的函数必须以返回语句结束。这是语言规范要求的,编译器会强制执行。
为什么编译器让我相信不需要使用类似 pt = new(Point) 这样的语句进行分配?
编译器为指针分配了空间(这就是你返回的内容),但它无法知道实际的 Point 对象的内存应该在哪里。这是你的责任。
这是编译器的另一个错误吗?
不是的。这是基本的知识。你在这样明显的代码中发现这样的错误的机会基本上是零。
英文:
> Will the compiler always allocate any function's named returned value?
Yes, absolutely.
> Also, why do I need to add the return statement at the end of the function? Is this a bug with the compiler?
Because function which return a value must end in a return statement. That's what the language spec requires and the compiler enforces.
> Why is the compiler letting me believe an allocation with a statement such as pt = new(Point) is not needed?
The compiler allocates space for the pointer (that's what you return) but he cannot know where the memory for the actual Point shall be. That's your job.
> Is this another bug with the compiler?
No. Such stuff is fundamental. The chances you discover such a bug in such obvious code is basically zero.
答案2
得分: 1
在下面的代码示例中,我可以假设我不需要分配返回值吗?编译器会始终分配任何函数的命名返回值吗?
我假设你所说的分配并不是指像这样的赋值:
a := func(1,2)
在这种情况下,编译器会将func的输出赋值给a。
但我想你是指分配函数结果变量。
-
是的,在这种情况下,你不需要分配,因为这只是一个值。
-
不是的。这取决于值是指针还是具体类型。对于具体类型,你在任何情况下都不需要分配。
此外,为什么我需要在函数末尾添加return语句?这是编译器的一个错误吗?
根据标准规定:
如果函数的签名声明了结果参数,函数体的语句列表必须以终止语句结束。
而且这个结果可以有名字,也可以没有。
代码会编译通过,但我得到了一个运行时错误!为什么编译器让我相信像pt = new(Point)这样的语句不需要分配?这是编译器的另一个错误吗?
这不是一个错误。这是因为编译器不关心指针指向的具体类型是什么。它会创建一个具有零值nil的指针。你需要自己处理它。否则,你会得到空指针解引用错误,因为你还没有将其指向任何具体类型。
英文:
> In the following code sample, can I assume that I don't need to allocate the returned value? Will the compiler always allocate any function's named returned value?
I assume by allocate you don't mean assigning like this:
a := func(1,2)
In this case, compiler will assign whatever comes out of func to a.
But I think you mean allocating function result variables.
1. Yes, in this case you don't need to allocate as this is just a value.
2. Nope. It depends whether value is a pointer or a concrete type. In concrete type, you don't need to allocate in any case.
> Also, why do I need to add the return statement at the end of the function? Is this a bug with the compiler?
Now to return part, according to standard:
> If the function's signature declares result parameters, the function body's statement list must end in a terminating statement.
And this result can be named or not.
> The code will compile but I am getting a runtime error! Why is the
> compiler letting me believe an allocation with a statement such as pt
> = new(Point) is not needed? Is this another bug with the compiler?
It isn't a bug. It's happening because compiler doesn't care about which concrete type a pointer's point. Its create a pointer with zero value of nil. You need to take care of it. Otherwise, you get nil pointer dereference as you still haven't pointed it to any concrete type.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论