如前所述,是的,规范允许您返回值(作为非指针)或指针。这只是你必须做出的决定。
什么时候返回指针?
通常如果您返回的值作为指针“更有用”。什么时候比较有用?
例如,如果有许多带有指针接收器的方法。是的,您可以将返回值存储在变量中,因此它将是可寻址的,并且您仍然可以调用具有指针接收器的方法。但如果立即返回指针,则可以“链接”方法调用。看这个例子:
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)
但是,如果返回一个指针,则有效:
func createMy(i int) *My { return (*My)(&i) }
此外,如果您将返回的值存储在不可寻址的数据结构中(map
例如),您无法通过索引映射来调用值的方法,因为映射的值不可寻址。
看这个例子:My.Str()
有指针接收器。所以如果你尝试这样做:
m := map[int]My{0: My(12)}
m[0].Str() // Error!
你不能因为“无法获取以下地址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
指针有用的另一个例子是如果这是一个“大”结构,会被多次传递. http.Request https://golang.org/pkg/net/http/#Request是一个光辉的例子。它很大,通常会被大量传递给其他处理程序,并且它具有带有指针接收器的方法。
如果返回一个指针,通常表明返回的值如果作为指针存储和传递会更好。