網(wǎng)站首頁 編程語言 正文
unsafe 包
func Alignof(x ArbitraryType) uintptr func Offsetof(x ArbitraryType) uintptr func Sizeof(x ArbitraryType) uintptr type ArbitraryType int type Pointer *ArbitraryType
在unsafe包中,只提供了3個函數(shù),兩個類型。就這么少的量,卻有著超級強悍的功能。
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僅用于文檔目的,實際上并非不安全包的一部分。它表示任意Go表達式的類型。 type ArbitraryType int
ArbitraryType 是以int為基礎(chǔ)定義的一個新類型,但是Go 語言unsafe包中,對ArbitraryType賦予了特殊的意義,通常,把interface{}看作是任意類型,那么ArbitraryType這個類型,在Go 語言系統(tǒng)中,比interface{}還要隨意。
Pointer
Pointer 是ArbitraryType指針類型為基礎(chǔ)的新類型,在Go 語言系統(tǒng)中,可以把Pointer類型,理解成任何指針的親爹。
Go 語言的指針類型長度與int類型長度,在內(nèi)存中占用的字節(jié)數(shù)是一樣的。ArbitraryType類型的變量也可以是指針。
// Alignof返回變量對齊字節(jié)數(shù)量 func Alignof(x ArbitraryType) uintptr // Offsetof返回變量指定屬性的偏移量,所以如果變量是一個struct類型,不能直接將這個struct類型的變量當(dāng)作參數(shù),只能將這個struct類型變量的屬性當(dāng)作參數(shù)。 func Offsetof(x ArbitraryType) uintptr // Sizeof 返回變量在內(nèi)存中占用的字節(jié)數(shù),切記,如果是slice,則不會返回這個slice在內(nèi)存中的實際占用長度。 func Sizeof(x ArbitraryType) uintptr
unsafe中,通過ArbitraryType 、Pointer 這兩個類型,可以將其他類型都轉(zhuǎn)換過來,然后通過這三個函數(shù),分別能取長度,偏移量,對齊字節(jié)數(shù),就可以在虛擬內(nèi)存中來回調(diào)度。
指針運算
- uintptr這個基礎(chǔ)類型,在Go 語言中,字節(jié)長度是與int一致。
- 通常Pointer不能參與指針運算,比如要在某個指針地址上加上一個偏移量,Pointer是不能做這個運算的
- 只有將Pointer類型先轉(zhuǎn)換成uintptr類型,做完地址加減法運算后,再轉(zhuǎn)換成Pointer類型,通過*操作達到取值、修改值的目的。
- unsafe.Pointer其實就是類似C的void *,在Go 語言中是用于各種指針相互轉(zhuǎn)換的橋梁,也即是通用指針。它可以讓任意類型的指針實現(xiàn)相互轉(zhuǎn)換,也可以將任意類型的指針轉(zhuǎn)換為 uintptr 進行指針運算。
- uintptr是Go 語言的內(nèi)置類型,是能存儲指針的整型, uintptr 的底層類型是int,它和unsafe.Pointer可相互轉(zhuǎn)換。
unsafe.Pointer和uintptr的區(qū)別
- unsafe.Pointer只是單純的通用指針類型,用于轉(zhuǎn)換不同類型指針,它不可以參與指針運算;
- 而uintptr是用于指針運算的,GC 不把 uintptr 當(dāng)指針,也就是說 uintptr 無法持有對象, uintptr 類型的目標(biāo)會被回收;
- unsafe.Pointer 可以和 普通指針 進行相互轉(zhuǎn)換;
- unsafe.Pointer 可以和 uintptr 進行相互轉(zhuǎn)換。
unsafe包簡單使用
準(zhǔn)備結(jié)構(gòu)體,成員不導(dǎo)出
初始化結(jié)構(gòu)體
func main() { s:=pkg.UnsafeStruct{} // {0 0} fmt.Println(s) }
眾所周知,結(jié)構(gòu)體的地址就是第一個成員的地址
func main() { s:=pkg.UnsafeStruct{} // 取成員1 field1Pointer:=unsafe.Pointer(&s) fmt.Println(field1Pointer) // 轉(zhuǎn)為int32類型指針 field1Ptr:=(*int32)(field1Pointer) fmt.Println(*field1Ptr) }
賦值,可以看到私有字段已經(jīng)被改變
func main() { s:=pkg.UnsafeStruct{} // 取成員1 field1Pointer:=unsafe.Pointer(&s) fmt.Println(field1Pointer) // 轉(zhuǎn)為int32類型指針 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類型指針 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類型指針 field2Ptr:=(*int64)(filed2Pointer) fmt.Println(*field2Ptr) // 賦值 *field2Ptr = 520 fmt.Println(s) }
成員聲明為int32和int64是為了避免對齊的影響,否則就要加上對齊值
總結(jié)
原文鏈接:https://blog.csdn.net/General_zy/article/details/128510696
相關(guān)推薦
- 2022-09-08 Python元組定義及集合的使用_python
- 2022-04-27 分布式Redis?Cluster集群搭建與Redis基本用法_Redis
- 2022-08-05 C語言庫函數(shù)qsort的使用詳解_C 語言
- 2022-11-07 python一招完美搞定Chromedriver的自動更新問題_python
- 2022-06-19 docker容器非root用戶提權(quán)的問題解決_docker
- 2023-11-17 Linux centos創(chuàng)建用戶以及賦予sudo權(quán)限
- 2021-12-09 Wide&Deep Model、Wide Model(LR)、Deep Model、Deep
- 2022-07-08 Python基礎(chǔ)篇之字符串的最全常用操作方法匯總_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支