最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解讀unsafe.Pointer和uintptr的區(qū)別

 更新時(shí)間:2023年02月10日 09:07:14   作者:Generalzy  
這篇文章主要介紹了解讀unsafe.Pointer和uintptr的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

unsafe 包

func Alignof(x ArbitraryType) uintptr
func Offsetof(x ArbitraryType) uintptr
func Sizeof(x ArbitraryType) uintptr
type ArbitraryType int
type Pointer *ArbitraryType

在unsafe包中,只提供了3個(gè)函數(shù),兩個(gè)類(lèi)型。就這么少的量,卻有著超級(jí)強(qiáng)悍的功能。

ArbitraryType

// ArbitraryType is here for the purposes of documentation only and is not actually
// part of the unsafe package. It represents the type of an arbitrary Goexpression.

// ArbitryType僅用于文檔目的,實(shí)際上并非不安全包的一部分。它表示任意Go表達(dá)式的類(lèi)型。
type ArbitraryType int

ArbitraryType 是以int為基礎(chǔ)定義的一個(gè)新類(lèi)型,但是Go 語(yǔ)言u(píng)nsafe包中,對(duì)ArbitraryType賦予了特殊的意義,通常,把interface{}看作是任意類(lèi)型,那么ArbitraryType這個(gè)類(lèi)型,在Go 語(yǔ)言系統(tǒng)中,比interface{}還要隨意。

Pointer

Pointer 是ArbitraryType指針類(lèi)型為基礎(chǔ)的新類(lèi)型,在Go 語(yǔ)言系統(tǒng)中,可以把Pointer類(lèi)型,理解成任何指針的親爹。

Go 語(yǔ)言的指針類(lèi)型長(zhǎng)度與int類(lèi)型長(zhǎng)度,在內(nèi)存中占用的字節(jié)數(shù)是一樣的。ArbitraryType類(lèi)型的變量也可以是指針。

// Alignof返回變量對(duì)齊字節(jié)數(shù)量
func Alignof(x ArbitraryType) uintptr
// Offsetof返回變量指定屬性的偏移量,所以如果變量是一個(gè)struct類(lèi)型,不能直接將這個(gè)struct類(lèi)型的變量當(dāng)作參數(shù),只能將這個(gè)struct類(lèi)型變量的屬性當(dāng)作參數(shù)。
func Offsetof(x ArbitraryType) uintptr
// Sizeof 返回變量在內(nèi)存中占用的字節(jié)數(shù),切記,如果是slice,則不會(huì)返回這個(gè)slice在內(nèi)存中的實(shí)際占用長(zhǎng)度。
func Sizeof(x ArbitraryType) uintptr

unsafe中,通過(guò)ArbitraryType 、Pointer 這兩個(gè)類(lèi)型,可以將其他類(lèi)型都轉(zhuǎn)換過(guò)來(lái),然后通過(guò)這三個(gè)函數(shù),分別能取長(zhǎng)度,偏移量,對(duì)齊字節(jié)數(shù),就可以在虛擬內(nèi)存中來(lái)回調(diào)度。

指針運(yùn)算

  • uintptr這個(gè)基礎(chǔ)類(lèi)型,在Go 語(yǔ)言中,字節(jié)長(zhǎng)度是與int一致。
  • 通常Pointer不能參與指針運(yùn)算,比如要在某個(gè)指針地址上加上一個(gè)偏移量,Pointer是不能做這個(gè)運(yùn)算的
  • 只有將Pointer類(lèi)型先轉(zhuǎn)換成uintptr類(lèi)型,做完地址加減法運(yùn)算后,再轉(zhuǎn)換成Pointer類(lèi)型,通過(guò)*操作達(dá)到取值、修改值的目的。
  • unsafe.Pointer其實(shí)就是類(lèi)似C的void *,在Go 語(yǔ)言中是用于各種指針相互轉(zhuǎn)換的橋梁,也即是通用指針。它可以讓任意類(lèi)型的指針實(shí)現(xiàn)相互轉(zhuǎn)換,也可以將任意類(lèi)型的指針轉(zhuǎn)換為 uintptr 進(jìn)行指針運(yùn)算。
  • uintptr是Go 語(yǔ)言的內(nèi)置類(lèi)型,是能存儲(chǔ)指針的整型, uintptr 的底層類(lèi)型是int,它和unsafe.Pointer可相互轉(zhuǎn)換。

unsafe.Pointer和uintptr的區(qū)別

  • unsafe.Pointer只是單純的通用指針類(lèi)型,用于轉(zhuǎn)換不同類(lèi)型指針,它不可以參與指針運(yùn)算;
  • 而uintptr是用于指針運(yùn)算的,GC 不把 uintptr 當(dāng)指針,也就是說(shuō) uintptr 無(wú)法持有對(duì)象, uintptr 類(lèi)型的目標(biāo)會(huì)被回收;
  • unsafe.Pointer 可以和 普通指針 進(jìn)行相互轉(zhuǎn)換;
  • unsafe.Pointer 可以和 uintptr 進(jìn)行相互轉(zhuǎn)換。

unsafe包簡(jiǎn)單使用

準(zhǔn)備結(jié)構(gòu)體,成員不導(dǎo)出

初始化結(jié)構(gòu)體

func main() {
	s:=pkg.UnsafeStruct{}
	// {0 0}
	fmt.Println(s)
}

眾所周知,結(jié)構(gòu)體的地址就是第一個(gè)成員的地址

func main() {
	s:=pkg.UnsafeStruct{}

	// 取成員1
	field1Pointer:=unsafe.Pointer(&s)
	fmt.Println(field1Pointer)
	// 轉(zhuǎn)為int32類(lèi)型指針
	field1Ptr:=(*int32)(field1Pointer)
	fmt.Println(*field1Ptr)
}

賦值,可以看到私有字段已經(jīng)被改變

func main() {
	s:=pkg.UnsafeStruct{}

	// 取成員1
	field1Pointer:=unsafe.Pointer(&s)
	fmt.Println(field1Pointer)
	// 轉(zhuǎn)為int32類(lèi)型指針
	field1Ptr:=(*int32)(field1Pointer)
	fmt.Println(*field1Ptr)

	// 賦值
	*field1Ptr = 10
	fmt.Println(s)
}

利用偏移量改變字段2的值

func main() {
	s:=pkg.UnsafeStruct{}

	// 取成員1
	field1Pointer:=unsafe.Pointer(&s)
	fmt.Println(field1Pointer)
	// 轉(zhuǎn)為int32類(lèi)型指針
	field1Ptr:=(*int32)(field1Pointer)
	fmt.Println(*field1Ptr)

	// 賦值
	*field1Ptr = 1314
	fmt.Println(s)

	// 獲取成員2的Pointer
	filed2Pointer:= unsafe.Pointer(uintptr(field1Pointer)+ unsafe.Sizeof(int64(0)))
	fmt.Println(filed2Pointer)
	// 轉(zhuǎn)為int64類(lèi)型指針
	field2Ptr:=(*int64)(filed2Pointer)
	fmt.Println(*field2Ptr)

	// 賦值
	*field2Ptr = 520
	fmt.Println(s)
}

成員聲明為int32和int64是為了避免對(duì)齊的影響,否則就要加上對(duì)齊值

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 一文帶你了解Golang中強(qiáng)大的重試機(jī)制

    一文帶你了解Golang中強(qiáng)大的重試機(jī)制

    在 Go 語(yǔ)言中,處理瞬態(tài)錯(cuò)誤是常見(jiàn)的挑戰(zhàn),這些錯(cuò)誤可能會(huì)在一段時(shí)間后自動(dòng)恢復(fù),因此,重試機(jī)制在這些情況下非常重要,所以本文就來(lái)和大家聊聊Golang中強(qiáng)大的重試機(jī)制吧
    2025-01-01
  • 獲取Golang環(huán)境變量的三種方式小結(jié)

    獲取Golang環(huán)境變量的三種方式小結(jié)

    本文介紹了Golang中獲取環(huán)境變量的三種方式,包含使用Viper包、GoDotEnv包和os包,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-11-11
  • golang time包下定時(shí)器的實(shí)現(xiàn)方法

    golang time包下定時(shí)器的實(shí)現(xiàn)方法

    定時(shí)器的實(shí)現(xiàn)大家應(yīng)該都遇到過(guò),最近在學(xué)習(xí)golang,所以下面這篇文章主要給大家介紹了關(guān)于golang time包下定時(shí)器的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-12-12
  • Go語(yǔ)言interface 與 nil 的比較

    Go語(yǔ)言interface 與 nil 的比較

    在golang中,nil只能賦值給指針、channel、func、interface、map或slice類(lèi)型的變量。如果未遵循這個(gè)規(guī)則,則會(huì)引發(fā)panic。
    2017-08-08
  • Golang?throttled基于GCRA速率限制庫(kù)使用探索

    Golang?throttled基于GCRA速率限制庫(kù)使用探索

    這篇文章主要為大家介紹了Golang?throttled基于GCRA速率限制庫(kù)使用實(shí)例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • 如何將Golang數(shù)組slice轉(zhuǎn)為逗號(hào)分隔的string字符串

    如何將Golang數(shù)組slice轉(zhuǎn)為逗號(hào)分隔的string字符串

    這篇文章主要介紹了如何將Golang數(shù)組slice轉(zhuǎn)為逗號(hào)分隔的string字符串問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • GoLang并發(fā)機(jī)制探究goroutine原理詳細(xì)講解

    GoLang并發(fā)機(jī)制探究goroutine原理詳細(xì)講解

    goroutine是Go語(yǔ)言提供的語(yǔ)言級(jí)別的輕量級(jí)線(xiàn)程,在我們需要使用并發(fā)時(shí),我們只需要通過(guò) go 關(guān)鍵字來(lái)開(kāi)啟 goroutine 即可。這篇文章主要介紹了GoLang并發(fā)機(jī)制goroutine原理,感興趣的可以了解一下
    2022-12-12
  • Go創(chuàng)建一個(gè)包并使用(導(dǎo)入本地包和注意事項(xiàng))

    Go創(chuàng)建一個(gè)包并使用(導(dǎo)入本地包和注意事項(xiàng))

    有時(shí)候需要自己寫(xiě)一個(gè)包方便多次使用,但是在導(dǎo)入自己寫(xiě)的包時(shí)遇到了問(wèn)題,本文主要介紹了Go創(chuàng)建一個(gè)包并使用(導(dǎo)入本地包和注意事項(xiàng)),感興趣的可以了解一下
    2023-11-11
  • PHP與Go語(yǔ)言之間的通信詳解

    PHP與Go語(yǔ)言之間的通信詳解

    相信大家都知道不同語(yǔ)言之間的通信方式有很多種,這篇文章詳細(xì)的介紹了PHP與Go語(yǔ)言之間如何通信,有需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。
    2016-10-10
  • GoZero實(shí)現(xiàn)數(shù)據(jù)庫(kù)MySQL單例模式連接的簡(jiǎn)單示例

    GoZero實(shí)現(xiàn)數(shù)據(jù)庫(kù)MySQL單例模式連接的簡(jiǎn)單示例

    在 GoZero 框架中實(shí)現(xiàn)數(shù)據(jù)庫(kù)的單例連接可以通過(guò)以下步驟來(lái)完成,GoZero 使用 gorm 作為默認(rèn)的數(shù)據(jù)庫(kù)操作框架,接下來(lái)我會(huì)展示一個(gè)簡(jiǎn)單的單例模式實(shí)現(xiàn),需要的朋友可以參考下
    2025-02-02

最新評(píng)論

称多县| 汉寿县| 呼伦贝尔市| 迭部县| 镇雄县| 宜昌市| 黔南| 同心县| 十堰市| 盐山县| 赣榆县| 达孜县| 乌兰县| 阿勒泰市| 荣昌县| 淮阳县| 东乌| 定襄县| 朝阳县| 鸡东县| 土默特右旗| 宜兰县| 湖口县| 资阳市| 闽清县| 黄骅市| 麻栗坡县| 鞍山市| 昭觉县| 新干县| 临安市| 勐海县| 镇远县| 嘉黎县| 清丰县| 临漳县| 万年县| 阿勒泰市| 霞浦县| 宁蒗| 永春县|