Go 傳 slice 是複製 header 而不是 pass by reference

Go 只有 pass by value,沒有 pass by reference。 傳 slice 進 function 時被複製的是那個三欄位的 slice header:複製了窗戶的,玻璃後面的房子還是同一間。

func f(w []string) { w[0] = "Hi" }        // 外面看得到
func g(w []string) { w = append(w, "x") } // 外面看不到
在 function 裡做的事外面看得到嗎為什麼
w[0] = "Hi"順著副本的 ptr,改到同一塊 array
w = []string{"XXX"}只換掉了副本的 ptr
w = append(w, "x")改的是副本的 len(或副本的 ptr)

第三列最容易誤解:cap 夠時,那個 "x" 確實被寫進了共用的 array,但呼叫端 header 的 len 沒變,所以它看不到那個元素。cap 不夠時更徹底——副本直接指向另一塊 array,兩邊從此無關。

如果真的是 pass by reference,第二、三列也會反映到外面。這正是為什麼 append 一定要寫成 s = append(s, x)呼叫端必須自己接回新的 header

跟 JS 傳物件的直覺一致:f(o){ o.a = 1 } 改得到,f(o){ o = {} } 改不到。

相關:Slice 是看向底層 array 的一扇窗戶append 的行為取決於 cap 夠不夠