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

huangapple 未分类评论153阅读模式
英文:

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

问题

最近我在学习Golang,并且意识到传递给Go函数的所有内容都会得到一个具有不同地址的相同类型的新副本。这是我们所说的按值传递吗?

所以基本上,除非我们直接传递地址,否则所有内容都会得到一个新的地址,就像下面这样:

Golang仍然一直如此一致。

但是对于Java来说,所有内容都是通过确切的内存地址传递的:

这真的违背了我的常识。因为我一直以为在Java中,对象是通过指针传递的,但显然这不是指针,因为它仍然具有与参数相同的地址。至于原始值,将获得一个新的副本和新的地址。但对于原始类型来说,它仍然是相同的地址。

Java和Golang都是按值传递,但为什么它们不同呢?

有人能给我一个明确的定义,关于引用、值和指针是什么,以及上述三个示例中使用的是引用、值和指针吗?最好能用不同的语言来回答这个问题。

英文:

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

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

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

huangapple
  • 本文由 发表于 2023年1月20日 22:32:13
  • 转载请务必保留本文链接:https://java.coder-hub.com/75185425.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定