I am recently studying golang and realize that everything passed to a go function get a new copy of same type with different address? Is it something what we call pass by value?
https://go.dev/play/p/eNvezQZrn8i
package main
import "fmt"
func fn(m map[int]int, s []int, i int) {
fmt.Printf("%p \n", &m)
fmt.Printf("%p \n", &s)
fmt.Printf("%p \n", &i)
m = make(map[int]int)
s = make([]int, 0)
i = 1
fmt.Printf("%p \n", &m)
fmt.Printf("%p \n", &s)
fmt.Printf("%p \n", &i)
}
func main() {
var m map[int]int
var s []int
var i int
fmt.Printf("%p \n", &m)
fmt.Printf("%p \n", m)
fmt.Printf("%p \n", &s)
fmt.Printf("%p \n", &i)
fn(m, s, i)
fmt.Println(m == nil)
fmt.Println(s == nil)
fmt.Println(i == 0)
fmt.Printf("%p \n", &m)
fmt.Printf("%p \n", &s)
fmt.Printf("%p \n", &i)
}
Output:
0xc00011a018
0x0
0xc000116018
0xc000122000
0xc00011a028
0xc000116030
0xc000122008
0xc00011a028
0xc000116030
0xc000122008
true
true
true
0xc00011a018
0xc000116018
0xc000122000
So basically everything gets a new address unless we directly pass in the address like below:
package main
import "fmt"
func fn(m *map[int]int, s *[]int, i *int) {
fmt.Printf("%p \n", m)
fmt.Printf("%p \n", s)
fmt.Printf("%p \n", i)
*m = make(map[int]int)
*s = make([]int, 0)
*i = 1
fmt.Printf("%p \n", &m)
fmt.Printf("%p \n", &s)
fmt.Printf("%p \n", &i)
}
func main() {
var m map[int]int
var s []int
var i int
fmt.Printf("%p \n", &m)
fmt.Printf("%p \n", &s)
fmt.Printf("%p \n", &i)
fn(&m, &s, &i)
fmt.Println(m == nil)
fmt.Println(s == nil)
fmt.Println(i == 0)
fmt.Printf("%p \n", &m)
fmt.Printf("%p \n", &s)
fmt.Printf("%p \n", &i)
}
https://go.dev/play/p/QLSBQd4Dbe0 output
0xc000012028
0xc000010030
0xc00001c030
0xc000012028
0xc000010030
0xc00001c030
0xc000012038
0xc000012040
0xc000012048
false
false
false
0xc000012028
0xc000010030
0xc00001c030
Golang still behaves consistently up to now.
But as for java, everything is passed by the exact memory address:
public class TestReferenceVsPointer {
public static void main(String[] args) {
Object obj = new Object();
int i = 1;
System.out.println("Object Memory address: " + VM.current().addressOf(obj));
System.out.println("int Memory address: " + VM.current().addressOf(i));
}
public static void print(Object obj, int i){
System.out.println("Object Memory address: " + VM.current().addressOf(obj));
System.out.println("int Memory address: " + VM.current().addressOf(i));
}
}
This is really against my common sense. AS I always thought in java object is passed by pointer but this is apparently not pointer because it still has the same address as the argument. As for primitive value will get a new copy and new address. But it is still same address for the primitive type.
Both java and golang have pass by value but why are they different?
Can anyone give me a clear definition as to what reference, value and pointer are and what the above three examples use: reference, value and pointer? It is better that you can use different languages to answer it