What is value, reference vs pointer and what these three example used to pass?

87 Views Asked by At

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

enter image description here

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

0

There are 0 best solutions below