iT邦幫忙

2021 iThome 鐵人賽

DAY 6
0
自我挑戰組

轉職未滿一年的點點滴滴系列 第 6

[Day 6] -『 GO語言學習筆記』- 值 vs. 指標(pointers)

  • 分享至 

  • twitterImage
  •  

以下筆記摘錄自『 The Go Workshop 』。

值的儲存

Go語言採用了一個簡單的記憶體管理系統叫堆疊(stack),每個參數都會在堆疊中獲得自己的記憶體,缺點是有越多值在函式之間傳遞,這樣重複的動作就會消耗越多的記憶體。

但其實還有一種在函式傳值得替代方式,使用的記憶體較少,這種方式不會複製值,而是建立稱指標(pointer)的東西傳遞給函式。

指標的儲存

建立一個指標後,Go語言會將值放在所謂的堆積(heap)記憶體空間,堆積允許一個值存在,直到沒有任何指標參照到他為止。Go語言會用所謂的垃圾回收機制(garbage collection)程序來回收這些記憶體。這種機制會在背景定期運作,無需特別操心。

Remark:
有時就算值沒有設置任何指標,也會因為其他原因被放進堆積裡面,值究竟該放到堆疊還是堆積上,我們無法介入,因為記憶體管理並非Go規格的一部分,而是被視為內部實作細節,所以上述所說的特性只是一般性指引,非鐵則。

指標會有未設定(is not set)的狀態,他沒有儲存目標值的地址時會回傳nil,而nil這個特殊值在Go語言中代表無值。

取得指標

  1. 把 * 算符放在型別前,以此方法宣告的指標變數初始值為nil。
var <變數> *<型別>
  1. 內建函式new()可以達到賦值。
<變數> := new(<型別>)
var <變數> = new(<型別>)
  1. 取得某個既有變數的指標使用 & 算符
<變數 1> := &<變數 2>

從指標取得值

若要真正取得指標的關聯值(及指標指向的記憶體所儲存的內容),必須把 * 算符放在變數前面解除(derederence)指標參照,真正取值。

<值> = *<指標變數>

常見錯誤是嘗試去解除一個無值指標(亦即nil),Go編輯器無法事先警告這點,所以最好養成習慣在解除指標的參照前,先檢查它是否是nil。

For example,

package main

import (
	"fmt"
)

func main() {
	var count1 *int
	count2 := new(int)
	countTemp := 5
	count3 := &countTemp

	if count1 != nil {
		fmt.Printf("count1: %#v\n", *count1)
	}
	if count2 != nil {
		fmt.Printf("count2: %#v\n", *count2)
	}
	if count3 != nil {
		fmt.Printf("count3: %#v\n", *count3)
	}
}

//輸出
count2: 0
count3: 5

上一篇
[Day 5] -『 GO語言學習筆記』- 宣告變數(variables)
下一篇
[Day 7] -『 GO語言學習筆記』- 指標函式設計 & 常數(constants)
系列文
轉職未滿一年的點點滴滴30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言