Go 理解命名返回类型的内存分配

Go 理解命名返回类型的内存分配,go,Go,在下面的代码示例中,我可以假设不需要分配返回值吗?编译器是否总是分配任何函数的命名返回值 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)) } 另外,为什么

在下面的代码示例中,我可以假设不需要分配返回值吗?编译器是否总是分配任何函数的命名返回值

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)
这样的语句分配?这是编译器的另一个bug吗?很明显,我在Go中遗漏了一些关于内存分配的关键内容

编译器是否总是分配任何函数的命名返回值

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语句?这是编译器的错误吗

因为返回值的函数必须以return语句结尾。这就是语言规范所要求的,编译器也会强制执行

为什么编译器让我相信不需要使用诸如pt=new(Point)之类的语句进行分配

编译器为指针分配空间(这是您返回的),但他不知道实际点的内存应该在哪里。那是你的工作

这是编译器的另一个bug吗

不,这些东西是基本的。在如此明显的代码中发现这样一个bug的机会基本上为零

编译器是否总是分配任何函数的命名返回值

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语句?这是编译器的错误吗

因为返回值的函数必须以return语句结尾。这就是语言规范所要求的,编译器也会强制执行

为什么编译器让我相信不需要使用诸如pt=new(Point)之类的语句进行分配

编译器为指针分配空间(这是您返回的),但他不知道实际点的内存应该在哪里。那是你的工作

这是编译器的另一个bug吗

不,这些东西是基本的。在如此明显的代码中发现这样一个bug的机会基本上为零

在下面的代码示例中,我可以假设不需要分配返回值吗?编译器是否总是分配任何函数的命名返回值

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))
}
我认为分配并不是指这样分配:

a := func(1,2)
在这种情况下,编译器将把func中的任何内容分配给a

但我认为你的意思是分配函数结果变量

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.
另外,为什么我需要在函数末尾添加return语句?这是编译器的错误吗

现在根据标准返回零件:

如果函数的签名声明结果参数,函数体的语句列表必须以终止语句结尾

这个结果可以命名,也可以不命名

代码将编译,但我得到一个运行时错误!为什么会这样 编译器让我相信一个带有语句(如pt)的分配 =不需要新的(点)?这是编译器的另一个bug吗

这不是虫子。之所以会发生这种情况,是因为编译器不关心指针指向哪个具体类型。它可以创建一个零值为nil的指针。你需要照顾它。否则,您将得到零指针解引用,因为您仍然没有将其指向任何具体类型

在下面的代码示例中,我可以假设不需要分配返回值吗?编译器是否总是分配任何函数的命名返回值

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))
}
我认为分配并不是指这样分配:

a := func(1,2)
在这种情况下,编译器将把func中的任何内容分配给a

但我认为你的意思是分配函数结果变量

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.
另外,为什么我需要在函数末尾添加return语句?这是编译器的错误吗

现在根据标准返回零件:

如果函数的签名声明结果参数,函数体的语句列表必须以终止语句结尾

这个结果可以命名,也可以不命名

代码将编译,但我得到一个运行时错误!为什么会这样 编译器让我相信一个带有语句(如pt)的分配 =不需要新的(点)?这是编译器的另一个bug吗


这不是虫子。之所以会发生这种情况,是因为编译器不关心指针指向哪个具体类型。它可以创建一个零值为nil的指针。你需要照顾它。否则,您将得到零指针解引用,因为您还没有将其指向任何具体类型。

谢谢。当您解释指针分配和结构分配之间的区别时,它“点击”。因为go并没有区分字段访问的指针和非指针,所以我想该语句仍然有效。再次感谢,谢谢。当您解释指针分配和结构分配之间的区别时,它“点击”。因为go并没有区分字段访问的指针和非指针,所以我想该语句仍然有效。再次感谢。