Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing by reference and value in Go to functions

Tags:

pointers

go

I am a bit confused about passing by reference and value in Go.

I've seen this explained of the * in front of a type.

  • in front of a type name, means that the declared variable will store an address of another variable of that type (not a value of that type).

This just doesn't make sense to me.

In Java if I was passing a Database instance into a function I would do

 databaseFunction(DatabaseType db) {
      // do something
}

However in the go example I have it's passed like so.

func PutTasks(db *sql.DB) echo.HandlerFunc {

}

Why do we need to have the asterisk in front of the type?

According to this cheat sheet, I found.

func PrintPerson(p *Person) ONLY receives the pointer address (reference)

I don't understand why I would only want to send a pointer address as a parameter.

like image 434
Elliot Pohath Avatar asked Nov 14 '17 22:11

Elliot Pohath


People also ask

Is Golang pass by value or pass-by-reference?

Go does not have pass-by-reference semantics because Go does not have reference variables.

Does Golang support pass-by-reference?

To be specific, Go does not support “Pass-By-Reference” semantic in any way. The reason is simple; Go does not support a reference variable as you have in other programming languages like C++.

What is passed by value and passed by reference in functions?

The difference between pass-by-reference and pass-by-value is that modifications made to arguments passed in by reference in the called function have effect in the calling function, whereas modifications made to arguments passed in by value in the called function can not affect the calling function.

Are Golang channels pass-by-reference?

Are channels implicitly passed by reference in go ? Yes, the reference types in Go are slice , map and channel . When passing these, you're making a copy of the reference.


2 Answers

First, Go technically has only pass-by-value. When passing a pointer to an object, you're passing a pointer by value, not passing an object by reference. The difference is subtle but occasionally relevant. For example, you can overwrite the pointer value which has no impact on the caller, as opposed to dereferencing it and overwriting the memory it points to.

// *int means you *must* pass a *int (pointer to int), NOT just an int!
func someFunc(x *int) {
    *x = 2 // Whatever variable caller passed in will now be 2
    y := 7
    x = &y // has no impact on the caller because we overwrote the pointer value!
}

As to your question "Why do we need to have the asterisk in front of the type?": The asterisk indicates that the value is of type pointer to sql.DB, rather than a value of type sql.DB. These are not interchangeable!

Why would you want to send a pointer address? So that you can share the value between the caller of a function and the function body, with changes made inside the function reflected in the caller (for example, a pointer is the only way that a "setter" method can work on an object). While Java passes objects by reference always, Go passes by value always (i.e. it creates a copy of the value in the function); if you pass something to a function, and that function modifies that value, the caller won't see those changes. If you want changes to propogate outside the function, you must pass a pointer.

See also: the Go tour section on Pointers, the Go spec section on pointers, the Go spec section on the address operators

like image 127
Adrian Avatar answered Oct 16 '22 16:10

Adrian


Pass by Reference :- When you pass a same variable into a function by different name.

Below example from C++ (as Go doesnt have this concept), where a and a1 are same variable.

void swap(int& a1, int& b1)
{
    int tmp = a1;
    a1 = b1;
    b1 = tmp;
}
 
int main()
{
    int a = 10, b = 20;
    swap(a, b);
    cout << "a " << a << " b " << b ;
}

Go passes everything as data( means it copies the data from current active frame to new active frame of new function). So if you pass values it copies the value and advantage is safety from accidental modification. And when it passes address of variable its copied also into the new pointer variables but has advantage of efficiency since size of pointer is smaller.

like image 27
Sumer Avatar answered Oct 16 '22 16:10

Sumer