GO值類型與引用類型


值類型

值類型包括基本數據類型,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底層數組是一樣的,但是上層切片不同,所以內存地址不一樣。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM