首頁 > 後端開發 > Golang > 主體

golang怎麼實現指標轉換

青灯夜游
發布: 2023-01-04 09:15:04
原創
5104 人瀏覽過

在golang中,可以利用unsafe套件來實現指標轉換,實現記憶體位址在不同指標型之間的轉換,進而更靈活地操作記憶體。例如unsafe套件下的Pointer()函數可以將任意變數的位址轉換成Pointer類型,也可以將Pointer型別轉換成任意的指標類型,Pointer型別是不同指標型別之間互轉的中間型別。

golang怎麼實現指標轉換

本教學操作環境:windows7系統、GO 1.18版本、Dell G3電腦。

在golang中,可以利用unsafe套件來實現指標轉換。

golang的指標轉換

Golang 提供了 unsafe 包,讓我們可以直接操作指定記憶體位址的記憶體。

unsafe套件下,有定義type Pointer *ArbitraryType(任意型別指標),可繞過GO的型別限制,type ArbitraryType int

  • 任何類型的指標值都可以轉換為Pointer。

  • Pointer可以轉換為任何類型的指標值。

  • uintptr可以轉換為Pointer。

  • Pointer可以轉換成uintptr。

透過 unsafe.Pointer() 函數,我們能夠取得變數的記憶體位址表示,本質上這是個整數。可以將任意變數的位址轉換成 Pointer 類型,也可以將 Pointer 類型轉換成任意的指標類型,它是不同指標類型之間互轉的中間類型。

golang怎麼實現指標轉換

但 Pointer 不支援運算,如果要在記憶體位址上進行加減運算,需要將其轉為 uintptr 類型。

下面我們嘗試讀取切片位址,並透過記憶體操作遍歷其內容:

package main

import "fmt"
import "unsafe"

func main() {
	// head = {address, 10, 10}
	// body = [1,2,3,4,5,6,7,8,9,10]
	var s = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	var address = (**[10]int)(unsafe.Pointer(&s))
	var len = (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&s)) + uintptr(8)))
	var cap = (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&s)) + uintptr(16)))
	fmt.Println(address, *len, *cap)
	var body = **address
	for i := 0; i < 10; i++ {
		fmt.Printf("%d ", body[i])
	}
}
----------
0xc000004460 10 10
1 2 3 4 5 6 7 8 9 10
登入後複製

golang怎麼實現指標轉換

上述程式碼中:

  • unsafe.Pointer(&s) 取得切片s 底層表示的第一個位置的記憶體位址,也即底層陣列的位址存放位址,

    透過(**[10]int)(unsafe .Pointer(&s)) 將其轉為**[10]int 類型指針,再透過**addrss 還原為數組;

  • unsafe.Pointer(uintptr(unsafe.Pointer( &s)) uintptr(8)) 透過位址運算,取得length 的存放位址,

    #進而透過(*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&s)) uintptr(8)))將length 記憶體轉為int 指標

    最後透過*len 取得切片長度;

    對於cap 的操作與len 類似,不再贅述;

#總之:

透過unsafe,我們能夠實現記憶體位址在不同指標型別間的轉換,進而更靈活地操作記憶體;

本實驗也進一步驗證了切片的底層儲存結構;

unsafe 在不是必須的條件下應該少使用,直接操作記憶體畢竟是風險較大的;

【相關推薦:Go影片教學程式教學

以上是golang怎麼實現指標轉換的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板