首頁 >後端開發 >Golang >golang指標傳遞和值傳遞的差別是什麼?

golang指標傳遞和值傳遞的差別是什麼?

青灯夜游
青灯夜游原創
2019-12-30 11:56:213450瀏覽

Go允許透過指標(有時稱為引用)和值來傳遞參數。在這篇文章中,我們將比較兩種方法,特別注意可能影響選擇的不同情境。

golang指標傳遞和值傳遞的差別是什麼?

指標傳遞與值傳遞

#嚴格地說,go方法或函數只有一種傳遞方式,那就是值傳遞。每次將一個變數作為參數傳遞時,都會建立一個新的變數副本並將其傳遞給所呼叫的函數或方法。副本分配在不同的記憶體位址。

在指標傳遞變數的情況下,將建立指向相同記憶體位址的新副本。為了感受它們之間的差異,讓我們來看看它是如何運作的。

值傳遞

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}

請注意,即使函數changeName將firstName更改為“Bob”,但更改不會影響main函數中的變數person。發生這種情況是因為函數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}

在這種情況下,函數main中的變數person在函數changeName中被修改。發生這種情況是因為&person和p是儲存在相同記憶體位址的相同結構的兩個不同指標。

變數不能被修改

我們沒有其他的選擇,只能透過值傳遞。所以這個變數不能在下游修改。反之亦然,如果變數被期望修改,它必須透過指標傳遞。

變數是一個大的結構

如果變數是一個大的結構,效能是一個問題,最好是透過指標傳遞變數。這樣可以避免在記憶體中複製整個結構。

變數是一個map或slice

Go中的map和slice是引用類型,應該透過值傳遞。

值傳遞通常開銷更小

即使Go看起來有點像C,它的編譯器運作方式也不同。 C的類比並不總是和Go一起工作。在Go中值傳遞可能比指標傳遞開銷更小。發生這種情況是因為Go使用逃逸分析來確定變數是否可以安全地分配到函數的堆疊幀上,這可能比在堆上分配變數開銷小的多。透過值傳遞可以簡化Go中的逃逸分析,並為變數提供更好的分配機會。

總結

指標傳遞和值傳遞的差異

1、指標傳遞傳遞的是一個位址,而非位址中的數據,傳遞資料較少,效率較值傳遞高,一般情況能用指標傳遞不用值傳遞。

2、指標傳遞時,呼叫函數中對指標所指向空間資料的修改會影響到呼叫者,因為他們指向的是同一塊區域,指傳遞就不會影響到呼叫者的資料。

相關推薦:golang教學

以上是golang指標傳遞和值傳遞的差別是什麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn