您好,登錄后才能下訂單哦!
指針
指針(pointer)在Go語言中可以被拆分為兩個核心概念:
類型指針,允許對這個指針類型的數(shù)據(jù)進行修改,傳遞數(shù)據(jù)可以直接使用指針,而無須拷貝數(shù)據(jù),類型指針不能進行偏移和運算。
切片,由指向起始元素的原始指針、元素數(shù)量和容量組成。
一個指針變量可以指向任何一個值的內(nèi)存地址,它所指向的值的內(nèi)存地址在 32 和 64 位機器上分別占用 4 或 8 個字節(jié),占用字節(jié)的大小與所指向的值的大小無關(guān)。當(dāng)一個指針被定義后沒有分配到任何變量時,它的默認(rèn)值為 nil。指針變量通??s寫為 ptr。
每個變量在運行時都擁有一個地址,這個地址代表變量在內(nèi)存中的位置。Go語言中使用在變量名前面添加&操作符(前綴)來獲取變量的內(nèi)存地址(取地址操作)
Go允許通過指針(有時稱為引用)和值來傳遞參數(shù)。在這篇文章中,我們將比較兩種方法,特別注意可能影響選擇的不同情境。
指針傳遞與值傳遞
嚴(yán)格地說,go方法或函數(shù)只有一種傳遞方式,那就是值傳遞。每次將一個變量作為參數(shù)傳遞時,都會創(chuàng)建一個新的變量副本并將其傳遞給所調(diào)用的函數(shù)或方法。副本分配在不同的內(nèi)存地址。
在指針傳遞變量的情況下,將創(chuàng)建指向相同內(nèi)存地址的新副本。為了感受它們之間的差異,我們來看看它是如何工作的。
值傳遞
package main import "fmt" type Person struct { firstName string lastName string } func changeName(p Person) { p.firstName = "Bob" } func main() { person := Person { firstName: "Alice", lastName: "Dow", } changeName(person) fmt.Println(person) }
運行代碼將得到以下輸出:
{Alice Dow}
請注意,即使函數(shù)changeName將firstName更改為“Bob”,但更改不會影響main函數(shù)中的變量person。發(fā)生這種情況是因為函數(shù)changeName修改了變量person的一個副本,而不是person本身。
指針傳遞
package main import "fmt" type Person struct { firstName string lastName string } func changeName(p *Person) { p.firstName = "Bob" } func main() { person := Person { firstName: "Alice", lastName: "Dow", } changeName(&person) fmt.Println(person) }
運行代碼將得到以下輸出:
{Bob Dow}
在這種情況下,函數(shù)main中的變量person在函數(shù)changeName中被修改。發(fā)生這種情況是因為&person和p是存儲在相同內(nèi)存地址的相同結(jié)構(gòu)的兩個不同指針。
變量不能被修改
我們沒有其他的選擇,只能通過值傳遞。所以這個變量不能在下游修改。反之亦然,如果變量被期望修改,它必須通過指針傳遞。
變量是一個大的結(jié)構(gòu)
如果變量是一個大的結(jié)構(gòu),性能是一個問題,最好是通過指針傳遞變量。這樣可以避免在內(nèi)存中復(fù)制整個結(jié)構(gòu)。
變量是一個map或slice
Go中的map和slice是引用類型,應(yīng)該通過值傳遞。
值傳遞通常開銷更小
即使Go看起來有點像C,它的編譯器工作方式也不同。C的類比并不總是和Go一起工作。在Go中值傳遞可能比指針傳遞開銷更小。發(fā)生這種情況是因為Go使用逃逸分析來確定變量是否可以安全地分配到函數(shù)的棧幀上,這可能比在堆上分配變量開銷小的多。通過值傳遞可以簡化Go中的逃逸分析,并為變量提供更好的分配機會。
總結(jié)
指針傳遞和值傳遞的區(qū)別
1、指針傳遞傳遞的是一個地址,而非地址中的數(shù)據(jù),傳遞數(shù)據(jù)較少,效率較值傳遞高,一般情況能用指針傳遞不用值傳遞。
2、指針傳遞時,調(diào)用函數(shù)中對指針?biāo)赶蚩臻g數(shù)據(jù)的修改會影響到調(diào)用者,因為他們指向的是同一塊區(qū)域,指傳遞就不會影響到調(diào)用者的數(shù)據(jù)。
以上就是golang指針傳遞和值傳遞的區(qū)別是什么?的詳細(xì)內(nèi)容,更多請關(guān)注億速云其它相關(guān)文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。