为什么 Go 的构造函数要返回地址? [英] Why should constructor of Go return address?

查看:45
本文介绍了为什么 Go 的构造函数要返回地址?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道 Go 没有任何构造函数,而是使用 New func 代替它,但根据 这个例子.

I understand that Go doesn't have any constructors and a New func is used in its place, but according to this example.

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

它们总是返回 &f.为什么仅仅返回 File 是不够的?

They always return &f. Why just simply returning File isn't suffice?

更新

我尝试为一个简单的结构返回创建的对象,这很好.所以,我想知道返回地址是构造函数还是什么的标准方式.

I've tried returning the created object for a simple struct and it's fine. So, I wonder if returning an address is a standard way of constructor or something.

谢谢.

推荐答案

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

As mentioned, yes, the spec allows you to return either values (as non-pointers) or pointers. It's just a decision you have to make.

什么时候返回指针?

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

Usually if the value you return is "more useful" as a pointer. When is it more useful?

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

For example if it has many methods with pointer receiver. Yes, you could store the return value in a variable and so it will be addressable and you can still call its methods that have pointer receivers. But if a pointer is returned right away, you can "chain" method calls. See this example:

type My int

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

func createMy(i int) My { return My(i) }

现在写:

fmt.Println(createMy(12).Str())

会报错:cannot call pointer method on createMy(12)

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

But if works if you return a pointer:

func createMy(i int) *My { return (*My)(&i) }

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

Also if you store the returned value in a data structure which is not addressable (map for example), you cannot call methods on values by indexing a map because values of a map are not addressable.

看这个例子:My.Str() 有指针接收器.因此,如果您尝试这样做:

See this example: My.Str() has pointer receiver. So if you try to do this:

m := map[int]My{0: My(12)}
m[0].Str() // Error!

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

You can't because "cannot take the address of m[0]". But the following works:

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

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

And another example for pointers being useful is if it is a "big" struct which will be passed around a lot. http.Request is a shining example. It is big, it is usually passed around a lot to other handlers, and it has methods with pointer receiver.

如果您返回一个指针,这通常表明返回值最好以指针形式存储和传递.

If you return a pointer, that usually suggests that the returned value is better if stored and passed around as a pointer.

这篇关于为什么 Go 的构造函数要返回地址?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆