为什么Go的构造函数返回地址? [英] Why should constructor of Go return address?
问题描述
我知道Go没有任何构造函数,并且使用 New func
代替它,但根据此示例。
func NewFile fd int,name string)* File {
if fd< 0 {
return nil
}
f:= File {fd,name,nil,0}
return& f
}
他们总是返回& f
。为什么只是简单地返回 File
还不够?
更新
我试图返回一个简单的结构的创建对象,它的罚款。所以,我不知道返回一个地址是一个标准的构造函数或某种东西。
谢谢。
如上所述,是的,规范允许你返回任何值(非指针)或指针。
$ b
何时返回指针?
>通常如果你返回的值是更有用作为指针。何时更有用?例如,如果它有多个带指针接收器的方法。是的,你可以将返回值存储在一个变量,所以它将是可寻址的,你仍然可以调用其方法具有指针接收器。但是如果一个指针立即返回,你可以链接方法调用。例如:
类型My int
func(m * My) return strconv.Itoa(int(* m))}
func createMy(i int)My {return My(i)}
现在写:
fmt.Println(createMy(12).Str ())
将导致错误:无法调用createMy 12)
但如果你能返回一个指针:
func createMy(i int)* My {return(* My)(& i)}
b $ b
此外,如果将返回值存储在不可寻址的数据结构中(例如, map
),则无法通过索引地图来对值调用方法因为地图的值不可寻址。
请参阅此示例: My.Str()
有指针接收器。所以如果你尝试这样做:
m:= map [int] My {0:My(12)}
m [0] .Str()//错误!
您不能因为不能使用 m [0]
。但以下工作:
m:= map [int] * My {}
my:= My )
m [0] =& my //在地图中存储一个指针
m [0] .Str()//可以调用它,不需要取地址m [0]
//因为它已经是一个指针
有用的是如果它是一个大结构将被传递很多。 http.Request
是闪亮的例子。它是大的,它通常传递给其他处理程序,并且它的方法与指针接收器。
如果你返回一个指针,通常表明返回值更好,如果存储和传递作为指针。
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
}
They always return &f
. Why just simply returning File
isn't suffice?
Update
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.
Thanks.
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.
When to return pointer?
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) }
Now writing:
fmt.Println(createMy(12).Str())
Will result in error: cannot call pointer method on createMy(12)
But if works if you return a pointer:
func createMy(i int) *My { return (*My)(&i) }
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.
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!
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
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屋!