Golang中在返回未被修改的变量前如何解引用
Golang中在返回未被修改的变量前如何解引用 你好,
由于 caller.go 永远不需要修改 result 变量,我相信我在 result.go 中对 result 变量进行解引用的做法是“好”的。我这样假设正确吗?这是在阅读了 https://github.com/golang/go/wiki/CodeReviewComments#receiver-type 后得出的结论。
另外,在 Go 语言中解引用(使用 * 操作符)并不会创建副本。它返回的是指针所指向的值。这意味着它不会在内存中分配额外的空间。这样理解对吗?
谢谢
// result.go
func NewResult(user entity.User) Result {
result := &Result{}
// 根据 `user` 更新 `result` 的所有属性。
// result.... = user....
return *result
}
// caller.go
func main() {
result := result.NewResult(User{//....})
// 对 `result` 进行一些操作,但不修改它。
fmt.Println(result)
}
更多关于Golang中在返回未被修改的变量前如何解引用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
这是一个替代解决方案,我认为它可以避免复制,除非编译器已经对此进行了优化。
func NewResult(user entity.User) (result Result) {
// 更新 `result` 中所有来自 `user` 的属性。
// result.... = user....
return
}
更多关于Golang中在返回未被修改的变量前如何解引用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
感谢提供宝贵的意见,所有这些都令人感激,帮助解答并澄清了疑问。
我之所以提出这个特定问题,主要原因是,我经常看到人们默认地在函数间传递或返回指针,即使他们并不修改其指向的值。作为一名学习者,我目前还无法对此提出强有力的反对论点,但我感觉,到处盲目地过度使用指针是一种有点不好的习惯。我认为大多数人遵循的是“如有疑问,使用指针”这一条,正如这里所提到的——但实际上这句话应该解读为“如有疑问,说明你并不知道自己在做什么” 😬
在 Go 中,你的理解基本正确。当返回 *result 时,确实会解引用指针并返回结构体的值副本。这不会创建额外的指针内存分配,但会复制整个结构体。
示例代码:
// result.go
type Result struct {
ID int
Name string
}
func NewResult(user entity.User) Result {
result := &Result{
ID: user.ID,
Name: user.Name,
}
// 解引用返回结构体值
return *result
}
// caller.go
func main() {
user := entity.User{ID: 1, Name: "John"}
result := NewResult(user)
// result 现在是值类型,调用者无法修改原始数据
fmt.Printf("%+v\n", result)
}
关于内存:解引用操作 *result 返回的是结构体的值,这个值会被复制到调用者的栈帧中。指针本身的内存(&Result{} 分配的内存)在函数返回后会被垃圾回收器回收,因为不再有引用指向它。
这种模式适用于:
- 调用者不需要修改返回的数据
- 结构体较小,复制开销可接受
- 希望保持 API 的不可变性
如果结构体很大,建议返回指针以避免复制开销,即使调用者不需要修改数据。Go 的逃逸分析通常会将这种小结构体分配在栈上,性能影响很小。
那样做是可行的,但我通常会:
func NewResult(user entity.User) Result {
var result Result
// 更新 `result` 中所有来自 `user` 的属性。
// result.... = user....
return result
}
省略指针,或者直接:
func NewResult(user entity.User) Result {
return Result{
// 所有属性以 Field: value 的形式列出
}
}
如果字段值不需要计算等操作,并且这样写看起来清晰的话。
Also dereferencing (using the
*operator) in Go doesn’t make a copy. It returns the value the pointer points to. This means it doesn’t allocate more space in memory. Is that correct?
也许吧?我的意思是,* 操作本身可能不会复制,但结果需要存放到某个地方。当返回结构体时,它需要在栈上。该栈空间由调用者分配并清零,因此我们需要将我们的结构体复制到其中。(你可以将返回值本身视为一个特殊的变量,其中 return result 类似于 preallocatedReturnValue = result。)我猜测上述所有代码片段都会导致一次内存复制(栈到栈),但内存复制成本非常低。它们都不应该导致需要避免的堆分配,这很好。编译器也有可能对此进行优化,在上述所有情况下直接写入返回值,但我不会指望这一点。而且无论如何这真的不重要。

