值類型
值類型包括基本數據類型,int,float,bool,string,以及數組和結構體(struct)。
值類型變量聲明后,不管是否已經賦值,編譯器為其分配內存,此時該值存儲於棧上。
值類型的默認值:
var a int //int類型默認值為 0
var b string //string類型默認值為 nil空
var c bool //bool類型默認值為false
var d [2]int //數組默認值為[0 0]
fmt.Println(&a) //默認已經分配內存地址,可以使用&來取內存地址
當使用等號=將一個變量的值賦給另一個變量時,如 j = i ,實際上是在內存中將 i 的值進行了拷貝,可以通過 &i 獲取變量 i 的內存地址。此時如果修改某個變量的值,不會影響另一個。
//變量的賦值
var a =10 //定義變量a
b := a //將a的值賦值給b
b = 101 //修改b的值,此時不會影響a
fmt.Printf("a的值是%v,a的內存地址是%p\n",a,&a) //a的值是10,a的內存地址是0xc42000e228
fmt.Printf("b的值是%v,b的內存地址是%p\n",b,&b) //b的值是101,b的內存地址是0xc42000e250
//數組的賦值
var c =[3]int{1,2,3} //定義一個長度為3的int類型的數組
d := c //將數組c賦值給d
d[1] = 100 //修改數組d中索引為1的值為100
fmt.Printf("c的值是%v,c的內存地址是%p\n",c,&c) //c的值是[1 2 3],c的內存地址是0xc42000a180
fmt.Printf("d的值是%v,d的內存地址是%p\n",d,&d) //d的值是[1 100 3],d的內存地址是0xc42000a1a0
畫圖示例:

引用類型
引用類型包括指針,slice切片,map ,chan,interface。
變量直接存放的就是一個內存地址值,這個地址值指向的空間存的才是值。所以修改其中一個,另外一個也會修改(同一個內存地址)。
引用類型必須申請內存才可以使用,make()是給引用類型申請內存空間。
var a = []int{1,2,3,4,5}
b := a //此時a,b都指向了內存中的[1 2 3 4 5]的地址
b[1] = 10 //相當於修改同一個內存地址,所以a的值也會改變
c := make([]int,5,5) //切片的初始化
copy(c,a) //將切片acopy到c
c[1] = 20 //copy是值類型,所以a不會改變
fmt.Printf("a的值是%v,a的內存地址是%p\n",a,&a) //a的值是[1 10 3 4 5],a的內存地址是0xc42000a180
fmt.Printf("b的值是%v,b的內存地址是%p\n",b,&b) //b的值是[1 10 3 4 5],b的內存地址是0xc42000a1a0
fmt.Printf("c的值是%v,c的內存地址是%p\n",c,&c) //c的值是[1 20 3 4 5],c的內存地址是0xc42000a1c0
d := &a //將a的內存地址賦值給d,取值用*d
a[1] = 11
fmt.Printf("d的值是%v,d的內存地址是%p\n",*d,d) //d的值是[1 11 3 4 5],d的內存地址是0xc420084060
fmt.Printf("a的值是%v,a的內存地址是%p\n",a,&a) //a的值是[1 11 3 4 5],a的內存地址是0xc420084060
a,b,c底層數組是一樣的,但是上層切片不同,所以內存地址不一樣。