为什么Go的构造函数会返回地址?

Bho*_*sut 6 constructor pointers go

我知道Go没有任何构造函数,并且New func在它的位置使用了a ,但是根据这个例子.

func NewFile(fd int, name string) *File {
  if fd < 0 {
    return nil
  }
  f := File{fd, name, nil, 0}
  return &f
}
Run Code Online (Sandbox Code Playgroud)

他们总是回来&f.为什么只是回归File是不够的?

更新

我已经尝试将创建的对象返回到一个简单的结构,它很好.所以,我想知道返回地址是否是构造函数的标准方法.

谢谢.

icz*_*cza 15

如上所述,是的,规范允许您返回值(作为非指针)或指针.这只是你必须做出的决定.

什么时候返回指针?

通常,如果返回的值作为指针"更有用".什么时候更有用?

例如,如果它有许多带指针接收器的方法.是的,您可以将返回值存储在变量中,因此它是可寻址的,您仍然可以调用其具有指针接收器的方法.但是如果立即返回指针,则可以"链接"方法调用.看这个例子:

type My int

func (m *My) Str() string { return strconv.Itoa(int(*m)) }

func createMy(i int) My { return My(i) }
Run Code Online (Sandbox Code Playgroud)

现在写:

fmt.Println(createMy(12).Str())
Run Code Online (Sandbox Code Playgroud)

会导致错误: cannot call pointer method on createMy(12)

但是如果你返回一个指针就行了:

func createMy(i int) *My { return (*My)(&i) }
Run Code Online (Sandbox Code Playgroud)

此外,如果将返回的值存储在不可寻址的数据结构中(map例如),则无法通过索引映射来调用值的方法,因为映射的值不可寻址.

看这个例子:My.Str()有指针接收器.所以如果你试着这样做:

m := map[int]My{0: My(12)}
m[0].Str() // Error!
Run Code Online (Sandbox Code Playgroud)

你不能因为"不能拿地址m[0]".但以下工作:

m := map[int]*My{}
my := My(12)
m[0] = &my // Store a pointer in the map

m[0].Str() // You can call it, no need to take the address of m[0]
           // as it is already a pointer
Run Code Online (Sandbox Code Playgroud)

另一个有用的指针示例是,如果它是一个"大"结构,它将被传递很多.http.Request是一个光辉的榜样.它很大,通常会传递给其他处理程序,它有指针接收器的方法.

如果返回一个指针,通常表明返回的值如果存储并作为指针传递则更好.