終於跨入第 11 天,今天要來了解在 Go 裡面我很不理解的一個型別 -- Pointer。
話不多說,我們就進入正題吧 ─=≡Σ(((っ゚∀゚)っ
變數就像一格一格的抽屜,只要在一定的規則內,都能夠去更動這個小抽屜裡面放的東西。
舉例來說有一個 A抽屜
,我在裡面放了一顆石頭,這個石頭就會是 A抽屜
內的值。如果我想要 B抽屜
的內容是跟 A抽屜
是一樣的,就會去複製他裡面的內容放進自己的抽屜,這就是「傳值」的概念。
但 Pointer 是指向一個記憶體位址,並不是透過複製相同的值來更改變數。
再拿抽屜當做例子,A抽屜
裡面有一支筆,而我讓 B抽屜
使用 pointer 的方式讓櫃子內容指向 A抽屜
,雖然看起來 B抽屜
跟 A抽屜
的內容會相同,但是當更改 B抽屜
的內容時 A抽屜
也會跟著變動。
簡單來說大概是這個概念
會以 *type
定義一個 pointer 型態:
var p *int
此時的 p
還不知道會去指向哪個 int 型態的變數記憶體位置,
如果要讓 pointer 去指向某個變數,會使用 &
符號。
package main
import "fmt"
func main() {
var p *int
i := 42
p = &i
fmt.Println(p)
}
// => 0xc00001a170
如果有實際執行看看這段程式碼的人,應該就會發現印出來的 p
並不是 i
的值,而是一串很像亂碼的東西,那個東西就是指向的 i
變數的記憶體位置。
如果想要得到期望的資訊,需要加上 *
,透過 pointer 讀取到記憶體的值。
package main
import "fmt"
func main() {
var p *int
i := 42
p = &i
fmt.Println(*p)
}
// => 42
還記得剛剛提到 B抽屜
如果透過 pointer 的方式修改內容,就會更改到 A抽屜
的值嗎?我們來實踐看看吧!
package main
import "fmt"
func main() {
var p *int
i := 42
p = &i
*p = 10
fmt.Println(i)
}
// => 10
一樣在 p
前加上 *
就會是以 pointer 的方式直接去改變記憶體位置的值。這樣最後 i
得出來的內容就會是 *p
賦值的 10 了!
pointer 的介紹差不多就到這邊,有任何問題歡迎與我指教 :)
本篇文章同步發佈於 我的部落格