大家都知道,Go 語言中,數組是分配連續內存的,也就是說,在函數中傳遞一個大數組,代價是很高的,例如:
// 聲明瞭一個8 MB 的數組
// 8 * 10^8 = 8 * 100000000 Bit
array := [1e6]int
// 將入有個 foo() 函數
foo(array)
這樣的話,每次調用 foo()
函數的時候,都會在棧上分配8 MB 的內存,因爲函數之間傳遞變量時,是值傳遞的,也就是不管這個變量的數組有多大,都會完整複製,然後傳遞給函數。
這就是爲什麼有時候會見到一個函數可以接受一個指針類型的參數。如下:
// 聲明瞭一個8 MB 的數組
// 8 * 10^8 = 8 * 100000000 Bit
array := [1e6]int
// 將入有個 foo() 函數
foo(&array)
這樣的開銷就小得多了,因爲這個參數其實是將數組的地址傳入了函數,而不是數組本身的值,而一個內存地址,只需要在展示棧上分配8個字節就夠用了。
但是,這樣也會帶來另外一種風險,就是當你修改了這個指針指向的值,那麼由於共享內存,傳入這個函數的指針指向的值,也會被改變。