golang中對「引用傳遞」的誤解

前情提要

最近看不少教程或者說博客上都說 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

思考解說

也就是說傳入和實際接收的值都是指針變量,這個兩個指針變量 vada 的值都爲指針所指向的變量 va 的地址 0xc000018658shell

而後再看函數內部的這個傳入的這個指針 a 的地址(指針)0xc000006060,對比外面存放指針 vad 的地址 0xc000006058,這兩個值是不同的,說明指針類型也是值傳遞,也就是說複製了一份指針的值傳遞給函數。函數

因此來講,函數 test 內部的 a 變量和外部的 vad 變量徹底不是同一個東西,avad的複製體,可是這兩個變量的值存放的都是va變量的地址,因此操做 a 會對變量 va產生修改。測試

從這裏來看,我的以爲「 slice、map、channel、func 都是引用傳遞」的表述方式感受容易引發誤解,會懷疑golang的設計對這幾個東西特殊對待,是引用傳遞。設計

實際上golang的設計,全部類型都是以的形式傳遞。只不過對這幾種類型來講,底層的實現就是這幾種類型的數據建立成功後,變量所接收的數據是這些類型所對應的地址,或者說被賦值的變量所接受到的是這幾種類型的值的地址。而不該該是這幾種類型在傳遞的時候是什麼引用類型。指針

相關文章
相關標籤/搜索