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.
Go does not have pass-by-reference semantics because Go does not have reference variables.
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++.
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 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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With