偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

終極真相:Go 中的參數(shù)傳遞

開發(fā) 后端
正確理解參數(shù)傳遞語義,可避免誤判內(nèi)存行為、消除隱蔽 bug,使代碼行為更加可預(yù)測。

在 Go 社區(qū)常能聽到“按值傳遞”“按引用傳遞”兩種說法:

  • 基本類型、數(shù)組、結(jié)構(gòu)體被稱為“按值”;
  • 指針、切片、映射、通道則被稱為“按引用”。

然而,上述分類容易造成誤解。在 Go 語言中,一切函數(shù)實參都以 值 的形式被復(fù)制傳遞。區(qū)別僅在于:

  • 復(fù)制的是“完整數(shù)據(jù)”(整數(shù)、數(shù)組等);
  • 復(fù)制的是“描述符”或指針(切片、映射、字符串等)。

理解這一點(diǎn)后,再看各類示例便能水落石出。

純值類型:數(shù)組、結(jié)構(gòu)體等

func do(b [3]int) int {
    b[0] = 0         // 只修改副本
    return b[1]
}

func main() {
    a := [3]int{1, 2, 3}
    v := do(a)       // 傳參時完整復(fù)制
    fmt.Println(a, v) // [1 2 3] 2
}
  • a 在調(diào)用處被整體復(fù)制后傳入 do;
  • do 內(nèi)部的任何修改都作用于該副本,原始數(shù)組保持不變。
  • 若想在被調(diào)函數(shù)內(nèi)部改動調(diào)用者的數(shù)組,需改為 *[3]int。

描述符類型:映射(map)

func do(m map[int]int) {
    m[3] = 1
    m[4] = 3
}

func main() {
    m := map[int]int{4: 2}
    do(m)                      // 僅復(fù)制 map 頭部(指針)
    fmt.Println(m)             // map[3:1 4:3]
}
  • 傳入的 是一個指向運(yùn)行時哈希表的指針副本;
  • 副本與原指針指向同一底層數(shù)據(jù),因此鍵值修改對調(diào)用者可見;
  • 若在函數(shù)內(nèi)執(zhí)行 m = make(map[int]int),只會修改本地副本,不影響調(diào)用者。

切片:三字節(jié)描述符的特殊性

func do(s []int) int {
    s = append(s, 4) // 可能觸發(fā)重新分配
    s[0] = 0
    return s[1]
}

func main() {
    a := []int{1, 2, 3}         // len=3 cap=3
    v := do(a)                  // 復(fù)制切片頭部
    fmt.Println(a, v)           // [1 2 3] 2
}
  • 切片頭部 = 指針 + 長度 + 容量。
  • append 時容量不足會 分配新數(shù)組 并返回新的切片頭部;
  • 該新頭部僅存在于 do 中,調(diào)用者仍指向舊數(shù)組,因此 a[0] 未被修改。

若確需影響調(diào)用方切片的長度/容量,可顯式傳入 *[]T:

func do(s *[]int) {
    *s = append(*s, 4) // 直接改寫調(diào)用者變量
    (*s)[0] = 0
}

參數(shù)永遠(yuǎn)“不是別名”

Go 永遠(yuǎn)復(fù)制實參,將其存入被調(diào)函數(shù)棧幀;函數(shù)內(nèi)變量 絕不是調(diào)用方變量的別名。想要修改調(diào)用者的數(shù)據(jù):就傳遞能“間接定位”到它的東西(指針或接口值的內(nèi)部指針)。

類型

傳遞時被復(fù)制的內(nèi)容

何時能改到調(diào)用方數(shù)據(jù)

何時改不到

基本類型

整個值

總改不到

數(shù)組

整個數(shù)組

總改不到

結(jié)構(gòu)體

整個結(jié)構(gòu)體

總改不到

指針

指針本身

解引用后可改

修改指針本身

切片

指針+len+cap 描述符

修改底層數(shù)組元素

重新分配、改頭部

映射

指向哈希表的指針

改鍵值對

重新 make

通道

指向 channel 結(jié)構(gòu)的指針

發(fā)/收消息

重新 make

字符串

指針+len 描述符(數(shù)據(jù)只讀共享)

無(只讀)

任何寫操作

結(jié)論與建議

(1) 牢記:Go 只有按值傳遞。不要再談“按引用”,最多是“值里裝著指針”。

(2) 修改調(diào)用者數(shù)據(jù)的途徑只有兩種:

  • 傳遞指針(*T、**T……);
  • 傳遞內(nèi)部含指針的描述符(切片、map、通道)并操作其指向的共享數(shù)據(jù)。

(3) 重新分配(append、make 等)僅改變局部副本頭部,不會回寫調(diào)用方。

(4) 若你需要讓函數(shù)“生長”切片或重新綁定 map,使用指針語義:func f(s *[]T) 或 func g(m *map[K]V)。

正確理解參數(shù)傳遞語義,可避免誤判內(nèi)存行為、消除隱蔽 bug,使代碼行為更加可預(yù)測。

責(zé)任編輯:趙寧寧 來源: 令飛編程
相關(guān)推薦

2011-03-25 13:44:28

Java值傳遞

2025-02-12 10:51:51

2012-02-21 14:04:15

Java

2025-08-29 01:45:00

Go語言函數(shù)

2023-11-17 14:10:08

C++函數(shù)

2010-07-26 13:13:33

Perl函數(shù)參數(shù)

2017-12-05 08:53:20

Golang參數(shù)傳遞

2021-03-02 10:50:23

SpringMVC 參數(shù)JavaWeb

2024-04-28 11:36:07

LambdaPython函數(shù)

2024-09-19 20:59:49

2015-09-08 10:16:41

Java參數(shù)按值傳遞

2017-10-26 11:44:19

工具語言編寫

2012-06-19 14:35:24

JSPJava亂碼

2025-09-24 09:22:49

2023-03-09 16:39:23

Python傳遞參數(shù)

2023-03-29 23:23:00

MyBatis參數(shù)框架

2020-01-15 12:43:51

人工智能機(jī)器學(xué)習(xí)工程師

2018-04-28 15:51:33

Mybatis方式傳遞

2010-03-11 11:07:37

Python函數(shù)參數(shù)

2022-04-28 10:29:38

數(shù)據(jù)數(shù)據(jù)收集
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號