最近看不少教程或者說博客上都說 golang 中的 slice、map、channel、func
都是「引用傳遞」
,然而一方面又說 golang 中全部類型都是值傳遞,總感受有些雲裏霧裏的,因而我親自作了下測試和思考。golang
package main import ( "fmt" ) func test(a *int) { fmt.Println("傳入變量的值:", a) fmt.Println("傳入變量的地址:", &a) } func main() { va := 666 vad := &va fmt.Println("須要傳入的值:", vad) fmt.Println("須要傳入的值的地址", &vad) test(vad) }
須要傳入的值: 0xc000018658 須要傳入的值的地址 0xc000006058 傳入變量的值: 0xc000018658 傳入變量的地址: 0xc000006060
也就是說傳入和實際接收的值都是指針變量,這個兩個指針變量 vad
和 a
的值都爲指針所指向的變量 va
的地址 0xc000018658
。shell
而後再看函數內部的這個傳入的這個指針 a
的地址(指針)0xc000006060
,對比外面存放指針 vad
的地址 0xc000006058
,這兩個值是不同的,說明指針類型也是值傳遞,也就是說複製了一份指針的值傳遞給函數。函數
因此來講,函數 test
內部的 a
變量和外部的 vad
變量徹底不是同一個東西,a
是vad
的複製體,可是這兩個變量的值存放的都是va
變量的地址,因此操做 a
會對變量 va
產生修改。測試
從這裏來看,我的以爲「 slice、map、channel、func
都是引用傳遞」的表述方式感受容易引發誤解,會懷疑golang
的設計對這幾個東西特殊對待,是引用傳遞。設計
實際上golang
的設計,全部類型都是以值
的形式傳遞。只不過對這幾種類型來講,底層的實現就是這幾種類型的數據建立成功後,變量所接收的數據是這些類型所對應的地址,或者說被賦值的變量所接受到的是這幾種類型的值的地址。而不該該是這幾種類型在傳遞的時候是什麼引用類型。指針