复杂数据类型:
- 指针pointer
- 数组array
- 结构体struct,替代class
- 管道channel
- 函数(也是一种函数类型)
- 切片slice
- 接口interface
- map(类似hashmap,set),比较简单不复杂,相当于别的语言中的map,仅有此。
指针:
凡是涉及引用都涉及指针;
基本数据类型,变量存的就是值,也叫做值类型;
分析基本类型数据在内存中布局。
-
什么是指针变量:
package main import "fmt" func main() { var num int = 200 fmt.Println(&num) //num变量的内存地址0xXXXXXXXX var ptr *int = &num //指针变量是num变量的内存地址0xXXXXXXXX,即ptr=&num,ptr数据类型为指针 fmt.Println(ptr) //内存地址0xXXXXXXXX fmt.Println(*ptr) //内存地址0xXXXXXXXX对应的值,也就是num变量对应的变量值 fmt.Println(**&ptr) //*&ptr相同于ptr,**&prt==*prt,也就是取本内存地址0xXXXXXXXX的变量值 }
-
通过指针变量改变内存中的存储值:
package main import "fmt" func main() { var a int = 100 //变量值为100 var ptr *int = &a //定义一个指针变量,指向a的内存地址 *ptr = 200 //将内存地址对应的变量值修改为200 fmt.Println(a) //再打印a,对应变量值变为200 }
-
用指针修改字符串的值:
package main import "fmt" func main() { var b string = "shit!" var ptr1 *string = &b *ptr1 = "hit!" fmt.Println(b) }
-
值类型和引用类型:
- 值类型:基本数据类型,string,array,struct
- 引用类型:pointer,slice,map,channel,interface
- 内存逻辑上分为栈区和堆区:
值类型数据一般在栈区分配,变量直接赋值;
引用类型一般在堆区分配,变量存储是一个地址,这个地址对应的空间才是真正的存储数据(某个变量值),当没有任何变量引用该地址时,就变为垃圾被GC回收
由于堆栈都是逻辑概念,不用区分那么详细,有些编译器甚至把堆栈都合并了,Golang根据变量生命周期长短判定到底放在栈区还是堆区。