英文:
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));
}
}
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
专注分享java语言的经验与见解,让所有开发者获益!
评论