传递一个结构体和结构体的指针有什么区别,他们不是两个指针吗?

问题描述:

例如传递一个结构体和结构体的指针有什么区别,他们不是两个指针吗?

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指向结构本身的指针?为什么在修改函数中的结构时,行为会有差异?

golang是否在changeByValueStruct中创建了一个新的结构,它解析参数?

+0

结构值是一个结构值,而不是指向结构值的指针;指向结构值的指针是指针,而不是指向指针的指针。 Go文档中的内容给出了普通结构值是指针的印象? – Adrian

有在围棋传递参数只有一个办法,那就是通过价值。这意味着总是在传递参数时创建一个值的副本并将其传递给函数。

当您将指针作为参数传递时,引擎盖下会发生什么,该指针的副本被创建并传递给底层函数。它不应该与通过引用混淆。

让我们看一个例子,以更好地把握它: 包主要

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) 

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

会发生什么内部modifyValue功能是Point结构的一个完全不同的情况下被修改,所以调用时传递的值功能不受影响。

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

最有趣的一点是最后一个功能modifyReference。如果您熟悉其他语言中的传递引用范例,则您会期望能够完全修改引用的对象。无论如何,这不会发生。这是因为您正在修改作为参数传递的指针的副本

如果所有的东西都是按值传递的,你应该什么时候传递指针和值。传递值可确保调用者函数传递的结构不会遭受任何更改,因此,在需要时,请查找值。这样做的缺点是整个对象的拷贝被制作,如果它太大,内存就成了一个问题。

如果传递一个大结构作为参数,使用指针会更好,因为它节省了空间,但是失去了保证对象不会发生任何更改的保证。

将结构体传递给函数参数使值的副本。并且结构体的指针不传递。所以传递struct不能更新字段值。

package main 

import (
    "fmt" 
) 

type Foo struct { 
    value int 
} 

func PassStruct(foo Foo) { 
    foo.value = 1 
} 

func PassStructPointer(foo *Foo) { 
    foo.value = 1 
} 

func main() { 
    var foo Foo 

    fmt.Printf("before PassStruct: %v\n", foo.value) 
    PassStruct(foo) 
    fmt.Printf("after PassStruct: %v\n", foo.value) 

    fmt.Printf("before PassStructPointer: %v\n", foo.value) 
    PassStructPointer(&foo) 
    fmt.Printf("after PassStructPointer: %v\n", foo.value) 
} 

https://play.golang.org/p/AM__JwyaJa

+0

但在内部,一个包含struct的变量只是一个指向结构体的指针吗? – user3591466

+0

正如我在上面所说的,传递结构体制作值的拷贝。 – mattn

+0

因此,它创建一个具有不同地址的相同值的新结构? – user3591466