Java转Go的学习07-指针 和 make、new 分配内存
仅作java2go的简单记录,有错误烦请提出
合集整理:Java转Go的学习-合集
demo已上传git:https://gitee.com/yayako/go-learning.git
指针 和 make、new分配内存
本科是有学c++和Java两门课的,最终走上了Java的路,一方面是大环境,另一方面就是那时候觉得指针很烦,而Java正好没有指针。没想到转到了go后还是要重新捡起来。
指针
普通的变量对应了自己内存地址,而指针是一种特殊的变量,对应了另一个变量的内存地址。

&与*
谈到指针离不开谈 &
、*
两个符号,前者用于取地址,而后者则是指针运算符,可以标识指针类型,也可以表示一个指针变量所指向的存储单元。
以该结构体为例
1 2 3 4
| type Test struct { a int b int }
|
以下代码,分别以两种方式创建出了普通变量 t1
和指针变量 t2
,将其分别赋值给 tt1
和 tt2
后再分别改变原来的a值,最后打印出 tt1
和 tt2
的现值查看区别。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| var t1 Test = Test{a: 0, b: 0}
fmt.Printf("t1 值:%v,类型:%T,地址:%p\n", t1, t1, &t1)
tt1 := t1
fmt.Printf("tt1 值:%v,类型:%T,地址:%p\n", tt1, tt1, &tt1)
t1.a = 1 fmt.Println(t1) fmt.Println(tt1)
var t2 *Test = &Test{a: 0, b: 0}
fmt.Printf("t2 值:%v,类型:%T,地址:%p,指向地址:%p\n", t2, t2, &t2, t2)
tt2 := t2
fmt.Printf("tt2 值:%v,类型:%T,地址:%p,指向地址:%p\n", tt2, tt2, &tt2, tt2)
t2.a = 1 fmt.Println(t2) fmt.Println(tt2)
|
控制台中我们会发现普通变量 t1
赋值给 tt1
后两者在内存中分配的地址并不相同,而指针变量 t2
与 tt2
则还是指向同一个存储单元。
内存分配情况大致如下:

值类型与引用类型
值类型:直接存储数据,在声明时就会默认为其分配内存空间。go中的数组、基本数据类型、结构体都是值类型变量。
引用类型:持有数据的引用,在使用时不仅需要声明,还需要手动为其分配内存空间。go中的slice、map、channel都是引用类型变量。(Java中除了基本数据类型外,所有变量都是引用型变量。
用数组和slice举个与上述相同的例子,会发现效果一致。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| arr1 := [...]int{1, 2, 3}
fmt.Printf("arr1 值:%v,类型:%T,地址:%p\n", arr1, arr1, &arr1) arr2 := arr1
fmt.Printf("arr1 值:%v,类型:%T,地址:%p\n", arr2, arr2, &arr2)
arr1[0] = 4 fmt.Println("arr1 =", arr1) fmt.Println("arr2 =", arr2)
slice01 := []int{1, 2, 3}
fmt.Printf("slice01 值:%v,类型:%T,地址:%p,指向地址:%p\n", slice01, slice01, &slice01, slice01) slice02 := slice01
fmt.Printf("slice02 值:%v,类型:%T,地址:%p,指向地址:%p\n", slice02, slice02, &slice02, slice02)
slice02[0] = 0 fmt.Println("slice01 =", slice01) fmt.Println("slice02 =", slice02)
|
new与make
func new
内建函数new,分配内存,第一个实参为类型。其返回值为指向该类型的新分配的零值的指针。
使用 new
创建一个指针类型的数组进行上面的实验
1 2 3 4 5 6
| t := new(Test) tt := t
fmt.Printf("t 值:%v,类型:%T,地址:%p,指向的地址:%p\n", t, t, &t, t)
fmt.Printf("tt 值:%v,类型:%T,地址:%p,指向的地址:%p\n", tt, tt, &tt, tt)
|
func make
1
| func make(Type, size IntegerType) Type
|
内建函数make,分配并初始化一个类型为slice、map、或channel的对象,第一个实参为类型。make的返回类型与其参数相同,而不是指向它的指针。