go語言中的值類型:
int、float、bool、array、sturct等
值傳遞是指在調用函數時將實際參數復制一份傳遞到函數中,這樣在函數中如果對參數進行修改,將不會影響到實際參數
聲明一個值類型變量時,編譯器會在棧中分配一個空間,空間里存儲的就是該變量的值
go語言中的引用類型:
slice,map,channel,interface,func,string等
聲明一個引用類型的變量,編譯器會把實例的內存分配在堆上
string和其他語言一樣,是引用類型,string的底層實現struct String { byte* str; intgo len; };
但是因為string不允許修改,每次操作string只能生成新的對象,所以在看起來使用時像值類型。
所謂引用傳遞是指在調用函數時將實際參數的地址傳遞到函數中,那么在函數中對參數所進行的修改,將影響到實際參數。
需要注意的是:引用類型在函數的內部可以對它的值進行修改,但是如果給形參重新賦值,重新賦值后的形參再怎么修改都不會影響外面的實參了
nil可以賦值給引用類型(除string外)、error類型和指針類型
go語言中的指針類型:
一個指針變量指向了一個值的內存地址
當一個指針被定義后沒有分配到任何變量時,它的值為 nil。nil 指針也稱為空指針
一個指針變量通常縮寫為 ptr
其實引用類型可以看作對指針的封裝
空指針判斷:
if(ptr != nil) /* ptr 不是空指針 */ if(ptr == nil) /* ptr 是空指針 */
例子:
package main import "fmt" type pArr []int func (p *pArr) oopFunc() { (*p)[3] = 111 } type newFunc func(string) func strFunc(s string) { fmt.Printf("%T ", s[1]) //uint8 fmt.Println(s) //hello world } type Person struct { Name string Height int } func changeStruct(p Person) { p.Name = "李四" p.Height = 160 } func main() { //切片指針的使用 var ptr []*int i := 1 ptr = append(ptr, &i) fmt.Println("ptr:", *ptr[0]) //結構體是值類型 person := Person{ "張三", 180, } changeStruct(person) fmt.Println(person) //{張三 180} //func 可以作為參數進行傳遞 var nf newFunc nf = strFunc str := "hello world" nf(str) //uint8 hello world //類似面向對象的方法 p := make(pArr, 4) p.oopFunc() fmt.Println("p:", p) //p: [0 0 0 111] //值類型無法被改變 num := 1 valPass(num) fmt.Println("num:", num) //num: 1 //引用類型可以在函數中被改變 nums := []int{0, 1, 2, 3} RefPass(nums) fmt.Println("nums:", nums) //nums: [0 100 2 3] //形參可以改變引用類型的值,但不能夠形參重新賦值 RefPass2(nums) fmt.Println("nums:", nums) //nums: [0 100 2 3] //形參可以改變指針類型的值 n := new(int) *n = 111 PointPass(n) fmt.Println("n:", *n) //n: 12 //形參可以改變指針類型的值,但是對形參重新賦值,不會影響實參 PointPass2(n) fmt.Println("n:", *n) //n: 12 } //指針傳遞,對指針重新賦值,指針指向了新的地址,此時對形參做修改將不再影響外面的實參 func PointPass2(num *int) { num = new(int) *num = 13 } // 指針傳遞,普通用法 func PointPass(num *int) { *num = 12 } //引用傳遞,普通用法,這個會改變外面的實參 func RefPass(nums []int) { nums[1] = 100 } //引用傳遞,對形參重新賦值,不會改變外面的實參,形參指向了新的地址 func RefPass2(nums []int) { nums = []int{9, 8, 7, 6} } //值傳遞 func valPass(num int) { num = 5 }