Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between passing a struct and pointer of the struct, are they not both pointers?

Tags:

For example

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) 

And

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

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?

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

like image 976
user3591466 Avatar asked Jul 02 '17 16:07

user3591466


People also ask

What is the difference between pointer and structure?

A pointer is the address of that structure (or anything else) in memory. The structure is a “blueprint” of how to store the data in memory, the pointer is the location of the data in memory. The idea of a pointer is that rather than pass the data around your program, you pass the location of the data.

Is a struct a pointer?

A pointer pointing to a structure is called structure pointer. Structures and pointers in C together help in accessing structure members efficiently. Structure pointer declaration is similar to declaring a structure variable using the struct keyword followed by the type of structure it will point to.

Are structs passed by value in C?

A struct can be either passed/returned by value or passed/returned by reference (via a pointer) in C. The general consensus seems to be that the former can be applied to small structs without penalty in most cases.

When would you use a pointer to a struct?

Pointer to structure holds the add of the entire structure. It is used to create complex data structures such as linked lists, trees, graphs and so on. The members of the structure can be accessed using a special operator called as an arrow operator ( -> ).


1 Answers

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) } 

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.

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.

like image 162
bogdanciobanu Avatar answered Oct 11 '22 15:10

bogdanciobanu