為了一個簡單的例子,假設我們使用下面的代碼來讀取body一個 http Get 請求:func main() { resp, err := http.Get("http://google.com") defer resp.Body.Close() if err != nil { log.Fatalln(err) } bs := make([]byte, 99999) resp.Body.Read(bs) fmt.Println(string(bs))}據我所知,在 Go 中,變量按值傳遞給函數(因此函數使用傳遞值的副本而不是原始值本身);Go forRead方法的文檔是:type Reader interface { Read(p []byte) (n int, err error)}根據文檔,p []byte是類型[]byte而不是它的指針([]*byte);那么該resp.Body.Read方法如何直接訪問和編輯bs變量本身(不是指針)?
2 回答

動漫人物
TA貢獻1815條經驗 獲得超10個贊
reflect.SliceHeader 的切片類型定義
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
雖然slice是一個值,但是值的地址指向一個指針,所以在展開之前可以把slice當作一個ptr屬性。
Reader 接口修改 []byte 對象就像修改指針一樣。最后,Read 方法返回修改數據的長度,即n <= len(p).
切片觸發追加擴展后,會創建一個新切片。新切片的數據地址與擴展地址不同。
在 Go 中,channels、maps 和 slices 保存了一個數據地址,因此它們都可以顯示指針引用的性質;但是, slice append 方法在展開后會返回一個新的數據指針,并且會顯示出類似的值傳遞屬性。

慕容708150
TA貢獻1831條經驗 獲得超4個贊
在這里排隊:
bs := make([]byte, 99999)
當你制作一個切片時,你實際上創建了一個數組并接收到一個名為 bs(Slice) 的指向該數組的指針。現在 Go 隱含地為你做這件事,它是一個抽象層。
現在,排隊
resp.Body.Read(bs)
你實際上是在傳遞一個修改指針。resp.Body.Read(bs) 不會對你大喊大叫,因為你通過說“嘿 Read(),bs 不是指針,我保證。;)”來愚弄 Read()
- 2 回答
- 0 關注
- 129 瀏覽
添加回答
舉報
0/150
提交
取消