传递一个结构体和该结构体的指针有什么区别,难道它们都不都是指针吗? [英] What is the difference between passing a struct and pointer of the struct, are they not both pointers?

查看:406
本文介绍了传递一个结构体和该结构体的指针有什么区别,难道它们都不都是指针吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如

var myStructRef *Vertex
var myStruct Vertex
myStructRef = &Vertex{2, 3}
myStruct = Vertex{2, 3}

fmt.Println(myStructRef)
fmt.Println(myStruct)
changeByReferenceStruct(myStructRef)
changeByValueStruct(myStruct)
fmt.Println(myStructRef)
fmt.Println(myStruct)

还有

func changeByValueStruct(myStruct Vertex) {
    myStruct.X = 5
    fmt.Println(myStruct)
}


func changeByReferenceStruct(myStruct *Vertex) {
    myStruct.X = 7
    fmt.Println(myStruct)
}

myStructRef *VertexmyStruct Vertex都不是指向结构本身的指针吗?为什么在修改函数中的结构时行为上会有差异?

Isn't both myStructRef *Vertex and myStruct Vertex a pointer pointing to the struct itself? Why is there a discrepancy in behavior when I modify the struct in a function?

golang在解析参数时是否在changeByValueStruct中创建新结构?

Is golang creating a new struct in changeByValueStruct when it resolves the parameter?

推荐答案

Go中仅有一种传递参数的方法,即按值.这意味着总是在传递参数时,会创建值的副本并将其传递给函数.

There's only one way of passing arguments in Go and that is by value. What that means is that always when passing an argument, a copy of the value is created and passed to the function.

当您将指针作为参数传递时,实际上是创建了该指针的副本并将其传递给基础函数.不应将其与传递引用混淆.

When you pass a pointer as an argument, what happens under the hood is that a copy of that pointer is created and passed to the underlying function. It should not be confused with pass-by-reference.

让我们看一个例子来更好地理解它:

Let's look at an example to better grasp it:

package main

import (
    "fmt"
)

type Point struct {
    x int
    y int
}

func (p Point) String() string {
    return fmt.Sprintf("(%d, %d)", p.x, p.y)
}

func modifyValue(point Point) {
    point.x += 10
}

func modifyPointer(point *Point) {
    point.x = 5
    point.y = 5
}

func modifyReference(point *Point) {
    point = &Point{5, 5}
}

func main() {
    p := Point{0, 0}
    fmt.Println(p) // prints (0, 0)

    modifyValue(p)
    fmt.Println(p) // prints (0, 0)

    modifyPointer(&p)
    fmt.Println(p) // prints (5, 5)

    p = Point{0, 0}
    modifyReference(&p)
    fmt.Println(p) // prints (0, 0)
}

modifyValue 函数内部发生的事情是修改了Point结构的完全不同的实例,因此调用该函数时传递的值不受影响.

What happens inside the modifyValue function is that a totally different instance of a Point structure is modified, so the value passed when calling the function is unaffected.

在第二个示例中,传递了指向该结构的指针,以便可以以从​​外部可见的方式修改该结构的字段.

In the second example, a pointer to the structure is passed so the fields of the structure can be modified in a way that is visible from outside.

最有趣的一点是最后一个功能 modifyReference .如果您熟悉其他语言提供的按引用传递"范例,则可以完全修改被引用的对象,但这不会发生.这是因为您正在修改作为参数传递的指针的副本.

The most interesting point is made by the last function, modifyReference. If you are familiar with the pass by reference paradigm available in other languages you would expect to be able to modify the referenced object altogether, but this doesn't happen. It's because you're modifying a copy of the pointer passed as argument.

您可能想知道,是否所有东西都按值传递,何时应传递指针以及何时传递值.传递值可确保调用方函数传递的结构不会受到任何更改,因此,当您需要此行为时,请选择该值.这样做的缺点是要复制整个对象,如果太大,就需要考虑内存问题.

You may wonder, if everything is passed by value, when should you pass pointers and when values. Passing values assures the caller function that the passed structure cannot suffer any changes, so when you need this behaviour, go for the value. The downside of this is that a copy of the entire object is made and, if it is too big, memory becomes a concern.

如果您要传递一个大结构作为参数,使用指针会更好,因为它可以节省空间,但是您无法保证该对象不会受到任何改变.

If you're passing a big structure as an argument, using a pointer is better because it saves space, but you lose the guarantee that the object won't suffer any changes.

这篇关于传递一个结构体和该结构体的指针有什么区别,难道它们都不都是指针吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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