簡體   English   中英

Golang 中的 *uint 和 uintptr 有什么區別?

[英]What's the difference between *uint and uintptr in Golang?

根據Golang tour ,我們提供了以下整數類型:

int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr

從理論上講,這意味着我們還可以擁有指向所有這些類型的指針,如下所示:

*int  *int8  *int16  *int32  *int64
*uint *uint8 *uint16 *uint32 *uint64 *uintptr

如果是這種情況,那么我們已經有一個指向 *uint 形式的 uint 的指針。 這將使 uintptr 變得多余。 官方文檔對此沒有太多說明:

uintptr is an integer type that is large enough to hold the bit pattern of any pointer.

據我了解,這意味着 uint 的位寬是在編譯時根據目標架構(通常是 32 位或 64 位)確定的。 指針寬度也應該縮放到目標架構似乎是合乎邏輯的(即:32 位 *uint 指向 32 位 uint)。 Golang 也是這樣嗎?

另一個想法是添加 uintptr 是為了在進行多個間接訪問時使語法不那么混亂(即: foo *uinptr vs foo **uint )?

我最后的想法是,指針和整數在 Golang 中可能是不兼容的數據類型。 這將是非常令人沮喪的,因為硬件本身並沒有對它們進行任何區分。 例如,“分支到此地址”指令可以使用來自同一寄存器的相同數據,該數據剛剛在“添加此值”指令中使用。

uintptr 的真正意義(雙關語)是什么?

簡短的回答是“永遠不要使用uintptr ”。 😀

長的答案是uintptr可以繞過類型系統並允許 Go 實現者在 Go 中編寫 Go 運行時庫,包括垃圾收集系統,並調用 C 可調用代碼,包括使用未處理的 C 指針的系統調用完全去。

如果你是一個實現者——例如,在新操作系統上提供對系統調用的訪問——你將需要uintptr 您還需要了解使用它所需的所有特殊魔法,例如,如果操作系統要對操作系統級線程執行堆棧式操作,則將 goroutine 鎖定到操作系統級線程。 (如果您將它與 Go 指針一起使用,您可能還需要告訴編譯器不要移動您的 goroutine 堆棧,這是通過特殊的編譯時指令完成的。)

編輯:正如kostix 在評論中指出的那樣,運行時系統將unsafe.Pointer視為對對象的引用,這使對象保持活動狀態以進行 GC。 不會uintptr視為此類參考。 (也就是說,雖然unsafe.Pointer具有指針類型,但uintptr具有整數類型。)另請參閱unsafe文檔

uintptr 只是內存地址的整數表示,而不管它指向的實際類型如何。 有點像 C 中的void * ,或者只是將指針轉換為整數。 它的目的是在不安全的黑魔法中使用,而不是在日常的 go 代碼中使用。

您將 uintptr 和 *uint 混為一談。 uintptr 在處理指針時使用,它是一種大到足以容納指針的數據類型。 主要用於不安全的內存訪問,看unsafe包。 *uint 是指向無符號整數的指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM