一、值类型和引用类型
值类型就是变量直接存储值,内存通常在栈中分配;引用类型就是变量存储的是一个值,这个地址对应的空间才是真正存储数据的值,内存通常在堆上分配。在Go语言中值类型和引用类型的数据类型有以下的分类。
1、值类型
- 基本数据类型(int系列、float系列、bool、string)
- 数组
- 结构体struct
2、引用类型
- 指针
- slice切片
- map
- 管道
- interface
...
二、指针
指针属于引用变量,所以它存储的值就是一个内存地址,而这个地址指向的空间存的才是数据值,比如:var ptr *int = &a ,&用于获取变量的地址,如var a int,获取变量a的地址使用 &a。
package main import "fmt" func main() { // 定义声明一个基本数据类型,其本身的内存地址 &i var a int = 10 // 定义声明一个指针变量 // 1、ptr是一个指针变量 // 2、ptr的数据类型是*int // 3、prt本身的内存地址是 &ptr var ptr *int = &a fmt.Printf("ptr=%v ", ptr) // ptr=0xc000014098 fmt.Printf("ptr的地址是%v ", &ptr) // ptr的地址是0xc000006028 fmt.Printf("ptr指向的值是%v ", *ptr) // ptr指向的值是10 }
通过内存图理解:
注意事项:
- 上图中可以通过*ptr去修改对应的a变量的值
- 值类型都有对应的指针类型,形式如 *值类型,比如int对应的指针类型就是*int,int64对应的指针类型就是*int64
对于下面的实例均是错误的使用方法:
package main import "fmt" func main() { // 错误的使用方法,指针存储的是内存地址,修改为var ptr *int = &a正确 var int a = 10 var ptr *int = a // 错误的使用方法,指针类型与值类型不匹配,修改为var ptr1 *int = &b正确 var int b = 20 var ptr1 *float32 = &b }