iT邦幫忙

2024 iThome 鐵人賽

DAY 14
1
Software Development

可以Go一輩子嗎?系列 第 14

Day14. 指標(pointer)的基本概念與操作

  • 分享至 

  • xImage
  •  

Day14. 指標(pointer)的基本概念與操作

在程式設計中,指標(Pointer)是一個強大且重要的概念,特別是在低階語言中,比如C/C++,高階語言由於各種原因使用到pointer的機會相對較少

概念

指標是用於它存儲的是另一個變數的記憶體地址的變數,Go語言跟其他語言一樣使用*&進行指標操作

  • *
    • 用於操作指標時,可以取得該指標指向變數的值(又稱dereferencing)
      • node = *headNode
    • 用於定義時,代表指定目標變數作為類別指標(又稱indirecting)
      • var p *int = &x
  • &: 作為引用,用於獲取變數的記憶體位置

需要注意的是,Go語言的pointer不能做到C語言那種指標算術

*(p++) // this doesn't work
*(p+10) // neither does this

函數傳參模式

變數傳送到function有兩種形式,分為Pass by value(call by value) 與Pass by reference (call by reference)
Go語言對於全部function的參數都是預設pass by value

  • Pass by value
    • 將被傳過去的變數複製一份後傳給function做為參數
    • 對function內變數修改不會影響外部變數
      func passByValue(v Value)
  • Pass by reference
    • 將被傳過去的變數的參考(記憶體位置)直接傳給function作為參數,也就是說兩個變數是同一個東西
    • 在function裡面的變更會影響到外部變數
      func passByReference(r *Reference)

But WHY?

首先,我們知道Go語言在傳遞參數給function時是透過pass-by-value, 因此當我們需要將一個非常大的struct或非常長的slice或array傳入參數的話會造成不必要的記憶體浪費。因此使用指標可以避免這種複製的行為,從而節省記憶體並提高效率。

此外,如果想透過呼叫method對屬性行修改(如ItemSetter),也需要透過pointer receiver來做到。

使用方式

最基礎的方式

var x int = 10
var p *int = &x
fmt.Printf("%p, %d", p, *p) // memory of x, 10

// edit
*p = 100
fmt.Printf("%p, %d, %d", p, *p, x) // memory of x, 100, 100

你也可以對pointer進行引用以獲取獲取記憶體位置,比如說我們要從Singly Linked List刪除指定Node

type ListNode struct{
    Val int
    Next *ListNode
}

var head *ListNode = CreateRandomListNode()
  • 一般的寫法
func removeListEntryBadTaste(entry *ListNode) {
    prev := nil
    walk := head
    for walk != entry{
        prev = walk
        walk = walk.next
    }
    
    if prev != nil{
        head = entry.next
    }else{
        prev.next = entry.next
    }
}
  • 透過對原本的head取引用的pointer(indirect)
func removeListEntryBadTaste(entry *ListNode) {
    var indirect **ListNode = &head
    for (*indirect) != entry{
        indirect = &((*indirect).next)
    }
    *(indirect) = entry.next
}

那麼今天的文章就到此告一段落,如果我的文章有任何地方有錯誤請在留言區反應。
明天將會介紹Go語言中的Goroutine介紹與使用
time

REF


上一篇
Day13. 結構化程式設計(2)
下一篇
Day15. Go語言中的Goroutine介紹與使用
系列文
可以Go一輩子嗎?31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言