婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識(shí)庫 > golang利用unsafe操作未導(dǎo)出變量-Pointer使用詳解

golang利用unsafe操作未導(dǎo)出變量-Pointer使用詳解

熱門標(biāo)簽:濱州自動(dòng)電銷機(jī)器人排名 阿里云ai電話機(jī)器人 浙江高頻外呼系統(tǒng)多少錢一個(gè)月 釘釘有地圖標(biāo)注功能嗎 建造者2地圖標(biāo)注 惠州電銷防封電話卡 汕頭小型外呼系統(tǒng) 鄭州亮點(diǎn)科技用的什么外呼系統(tǒng) 黃岡人工智能電銷機(jī)器人哪個(gè)好

前言

unsafe.Pointer其實(shí)就是類似C的void *,在golang中是用于各種指針相互轉(zhuǎn)換的橋梁。uintptr是golang的內(nèi)置類型,是能存儲(chǔ)指針的整型,uintptr的底層類型是int,它和unsafe.Pointer可相互轉(zhuǎn)換。uintptr和unsafe.Pointer的區(qū)別就是:unsafe.Pointer只是單純的通用指針類型,用于轉(zhuǎn)換不同類型指針,它不可以參與指針運(yùn)算;而uintptr是用于指針運(yùn)算的,GC 不把 uintptr 當(dāng)指針,也就是說 uintptr 無法持有對(duì)象,uintptr類型的目標(biāo)會(huì)被回收。golang的unsafe包很強(qiáng)大,基本上很少會(huì)去用它。它可以像C一樣去操作內(nèi)存,但由于golang不支持直接進(jìn)行指針運(yùn)算,所以用起來稍顯麻煩。

切入正題。利用unsafe包,可操作私有變量(在golang中稱為“未導(dǎo)出變量”,變量名以小寫字母開始),下面是具體例子。

在$GOPATH/src下建立poit包,并在poit下建立子包p,目錄結(jié)構(gòu)如下:

$GOPATH/src

----poit

--------p

------------v.go

--------main.go

以下是v.go的代碼:

package p

import (
 "fmt"
)

type V struct {
 i int32
 j int64
}

func (this V) PutI() {
 fmt.Printf("i=%d\n", this.i)
}

func (this V) PutJ() {
 fmt.Printf("j=%d\n", this.j)
}

意圖很明顯,我是想通過unsafe包來實(shí)現(xiàn)對(duì)V的成員i和j賦值,然后通過PutI()和PutJ()來打印觀察輸出結(jié)果。

以下是main.go源代碼:

package main

import (
 "poit/p"
 "unsafe"
)

func main() {
 var v *p.V = new(p.V)
 var i *int32 = (*int32)(unsafe.Pointer(v))
 *i = int32(98)
 var j *int64 = (*int64)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + uintptr(unsafe.Sizeof(int32(0)))))
 *j = int64(763)
 v.PutI()
 v.PutJ()
}

當(dāng)然會(huì)有些限制,比如需要知道結(jié)構(gòu)體V的成員布局,要修改的成員大小以及成員的偏移量。我們的核心思想就是:結(jié)構(gòu)體的成員在內(nèi)存中的分配是一段連續(xù)的內(nèi)存,結(jié)構(gòu)體中第一個(gè)成員的地址就是這個(gè)結(jié)構(gòu)體的地址,您也可以認(rèn)為是相對(duì)于這個(gè)結(jié)構(gòu)體偏移了0。相同的,這個(gè)結(jié)構(gòu)體中的任一成員都可以相對(duì)于這個(gè)結(jié)構(gòu)體的偏移來計(jì)算出它在內(nèi)存中的絕對(duì)地址。

具體來講解下main方法的實(shí)現(xiàn):

var v *p.V = new(p.V)

new是golang的內(nèi)置方法,用來分配一段內(nèi)存(會(huì)按類型的零值來清零),并返回一個(gè)指針。所以v就是類型為p.V的一個(gè)指針。

var i *int32 = (*int32)(unsafe.Pointer(v))

將指針v轉(zhuǎn)成通用指針,再轉(zhuǎn)成int32指針。這里就看到了unsafe.Pointer的作用了,您不能直接將v轉(zhuǎn)成int32類型的指針,那樣將會(huì)panic。剛才說了v的地址其實(shí)就是它的第一個(gè)成員的地址,所以這個(gè)i就很顯然指向了v的成員i,通過給i賦值就相當(dāng)于給v.i賦值了,但是別忘了i只是個(gè)指針,要賦值得解引用。

*i = int32(98)

現(xiàn)在已經(jīng)成功的改變了v的私有成員i的值,好開心_

但是對(duì)于v.j來說,怎么來得到它在內(nèi)存中的地址呢?其實(shí)我們可以獲取它相對(duì)于v的偏移量(unsafe.Sizeof可以為我們做這個(gè)事),但我上面的代碼并沒有這樣去實(shí)現(xiàn)。各位別急,一步步來。

var j *int64 = (*int64)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + uintptr(unsafe.Sizeof(int32(0)))))

其實(shí)我們已經(jīng)知道v是有兩個(gè)成員的,包括i和j,并且在定義中,i位于j的前面,而i是int32類型,也就是說i占4個(gè)字節(jié)。所以j是相對(duì)于v偏移了4個(gè)字節(jié)。您可以用uintptr(4)或uintptr(unsafe.Sizeof(int32(0)))來做這個(gè)事。unsafe.Sizeof方法用來得到一個(gè)值應(yīng)該占用多少個(gè)字節(jié)空間。注意這里跟C的用法不一樣,C是直接傳入類型,而golang是傳入值。之所以轉(zhuǎn)成uintptr類型是因?yàn)樾枰鲋羔樳\(yùn)算。v的地址加上j相對(duì)于v的偏移地址,也就得到了v.j在內(nèi)存中的絕對(duì)地址,別忘了j的類型是int64,所以現(xiàn)在的j就是一個(gè)指向v.j的指針,接下來給它賦值:

*j = int64(763)

好吧,現(xiàn)在貌視一切就緒了,來打印下:

v.PutI()
v.PutJ()

如果您看到了正確的輸出,那恭喜您,您做到了!

但是,別忘了上面的代碼其實(shí)是有一些問題的,您發(fā)現(xiàn)了嗎?

在p目錄下新建w.go文件,代碼如下:

package p

import (
 "fmt"
 "unsafe"
)

type W struct {
 b byte
 i int32
 j int64
}

func init() {
 var w *W = new(W)
 fmt.Printf("size=%d\n", unsafe.Sizeof(*w))
}

需要修改main.go的代碼嗎?不需要,我們只是來測(cè)試一下。w.go里定義了一個(gè)特殊方法init,它會(huì)在導(dǎo)入p包時(shí)自動(dòng)執(zhí)行,別忘了我們有在main.go里導(dǎo)入p包。每個(gè)包都可定義多個(gè)init方法,它們會(huì)在包被導(dǎo)入時(shí)自動(dòng)執(zhí)行(在執(zhí)行main方法前被執(zhí)行,通常用于初始化工作),但是,最好在一個(gè)包中只定義一個(gè)init方法,否則您或許會(huì)很難預(yù)期它的行為)。我們來看下它的輸出:

size=16

等等,好像跟我們想像的不一致。來手動(dòng)計(jì)算一下:b是byte類型,占1個(gè)字節(jié);i是int32類型,占4個(gè)字節(jié);j是int64類型,占8個(gè)字節(jié),1+4+8=13。這是怎么回事呢?這是因?yàn)榘l(fā)生了對(duì)齊。在struct中,它的對(duì)齊值是它的成員中的最大對(duì)齊值。每個(gè)成員類型都有它的對(duì)齊值,可以用unsafe.Alignof方法來計(jì)算,比如unsafe.Alignof(w.b)就可以得到b在w中的對(duì)齊值。同理,我們可以計(jì)算出w.b的對(duì)齊值是1,w.i的對(duì)齊值是4,w.j的對(duì)齊值也是4。如果您認(rèn)為w.j的對(duì)齊值是8那就錯(cuò)了,所以我們前面的代碼能正確執(zhí)行(試想一下,如果w.j的對(duì)齊值是8,那前面的賦值代碼就有問題了。也就是說前面的賦值中,如果v.j的對(duì)齊值是8,那么v.i跟v.j之間應(yīng)該有4個(gè)字節(jié)的填充。所以得到正確的對(duì)齊值是很重要的)。對(duì)齊值最小是1,這是因?yàn)榇鎯?chǔ)單元是以字節(jié)為單位。所以b就在w的首地址,而i的對(duì)齊值是4,它的存儲(chǔ)地址必須是4的倍數(shù),因此,在b和i的中間有3個(gè)填充,同理j也需要對(duì)齊,但因?yàn)閕和j之間不需要填充,所以w的Sizeof值應(yīng)該是13+3=16。如果要通過unsafe來對(duì)w的三個(gè)私有成員賦值,b的賦值同前,而i的賦值則需要跳過3個(gè)字節(jié),也就是計(jì)算偏移量的時(shí)候多跳過3個(gè)字節(jié),同理j的偏移可以通過簡(jiǎn)單的數(shù)學(xué)運(yùn)算就能得到。

比如也可以通過unsafe來靈活取值:

package main

import (
 "fmt"
 "unsafe"
)

func main() {
 var b []byte = []byte{'a', 'b', 'c'}
 var c *byte = b[0]
 fmt.Println(*(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(c)) + uintptr(1))))
}

關(guān)于填充,F(xiàn)astCGI協(xié)議就用到了。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

您可能感興趣的文章:
  • Golang常用環(huán)境變量說明與設(shè)置詳解
  • Golang中的變量學(xué)習(xí)小結(jié)
  • golang中值類型/指針類型的變量區(qū)別總結(jié)
  • Golang常見錯(cuò)誤之值拷貝和for循環(huán)中的單一變量詳解
  • 詳解Golang編程中的常量與變量
  • Golang學(xué)習(xí)筆記(二):類型、變量、常量
  • Golang 變量申明的三種方式

標(biāo)簽:東營(yíng) 滄州 昭通 晉中 駐馬店 瀘州 泰安 阿壩

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《golang利用unsafe操作未導(dǎo)出變量-Pointer使用詳解》,本文關(guān)鍵詞  golang,利用,unsafe,操作,未,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《golang利用unsafe操作未導(dǎo)出變量-Pointer使用詳解》相關(guān)的同類信息!
  • 本頁收集關(guān)于golang利用unsafe操作未導(dǎo)出變量-Pointer使用詳解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    男女激情视频一区| 精品国产亚洲在线| 欧美v亚洲v综合ⅴ国产v| 一区二区三区国产豹纹内裤在线| 国产精品一级在线| 国产午夜精品理论片a级大结局| 日本成人在线视频网站| 欧美一区二区三区四区久久| 欧美aⅴ一区二区三区视频| 91精品国产一区二区三区香蕉| 日韩高清国产一区在线| 日韩精品一区在线观看| 国产精品资源网站| 亚洲欧美偷拍另类a∨色屁股| 99精品国产视频| 亚洲超碰精品一区二区| 久久综合久久鬼色| 不卡电影一区二区三区| 亚洲mv在线观看| 亚洲国产乱码最新视频| 99久久免费精品| 日韩成人精品在线| 国产精品成人在线观看 | 4438成人网| 成人免费视频一区二区| 亚洲男人的天堂在线观看| 欧美一区二区三区性视频| 成人开心网精品视频| 日韩国产高清影视| 亚洲视频在线一区| 日本一区二区久久| 精品福利视频一区二区三区| 欧美视频一区二区| 福利一区福利二区| 奇米色一区二区| 日本系列欧美系列| 有码一区二区三区| 一区二区三区成人| 亚洲六月丁香色婷婷综合久久| 国产日产欧产精品推荐色| 欧美一区二区三区视频| 欧美日韩美少妇 | 亚洲精品乱码久久久久久黑人 | 国产麻豆一精品一av一免费| 亚洲国产精品一区二区久久恐怖片| 国产精品传媒在线| 亚洲精选免费视频| 亚洲一区二区三区免费视频| 1区2区3区精品视频| 亚洲日本欧美天堂| 一区二区三区精品视频在线| 亚洲综合成人网| 亚洲大片在线观看| 亚洲一级二级三级在线免费观看| 亚洲视频免费观看| 日韩专区中文字幕一区二区| 国产一区 二区 三区一级| 国产美女在线精品| 欧美视频在线一区二区三区| 欧美日韩精品欧美日韩精品一综合| 日韩一区二区高清| 国产精品久久久久久久久快鸭| 伊人色综合久久天天| 国内外成人在线| 欧美三级资源在线| 亚洲国产精品99久久久久久久久| 一区二区三区波多野结衣在线观看 | 国产成人在线视频网站| 一本色道a无线码一区v| 欧美大胆人体bbbb| 亚洲乱码国产乱码精品精98午夜 | 久久久久久久久久久久久夜| 亚洲色图欧美在线| 久久国产视频网| 欧美电影在线免费观看| 精品国产一区a| 无吗不卡中文字幕| 一本一本久久a久久精品综合麻豆 一本一道波多野结衣一区二区 | 亚洲人成精品久久久久| 亚洲成a人片在线不卡一二三区| 国产成人啪午夜精品网站男同| 欧美妇女性影城| 亚洲成人手机在线| 欧美羞羞免费网站| 亚洲国产乱码最新视频| 欧美性感一区二区三区| 亚洲欧美另类小说视频| 99re亚洲国产精品| 亚洲男人的天堂在线aⅴ视频| 国产一区二区福利视频| 欧美一区二区精品在线| 日韩成人av影视| 欧美一二三区在线| 国产一区二区三区免费在线观看| 欧美一区二区福利视频| 蜜臀99久久精品久久久久久软件| 欧美一区二区性放荡片| 国产一区二区三区国产| 国产精品久久久久aaaa樱花 | 国产麻豆精品一区二区| 精品99999| 日韩亚洲欧美成人一区| 亚洲丝袜自拍清纯另类| 久久99精品久久久久久国产越南| 午夜精品视频一区| 麻豆精品在线观看| 成人动漫视频在线| 777午夜精品视频在线播放| 日韩午夜激情av| 91农村精品一区二区在线| 日韩一区二区三区视频在线| 精品日韩一区二区三区| 青青草国产精品亚洲专区无| 五月激情综合网| 欧美日韩午夜影院| 午夜激情一区二区三区| 欧美mv和日韩mv的网站| 国产精品资源在线看| 亚洲男人天堂av| 久久久久久久网| 欧美性大战久久久久久久蜜臀| 精品一二三四在线| 亚洲一区日韩精品中文字幕| 在线不卡一区二区| 久久99精品国产麻豆婷婷| 国产精品免费丝袜| 成人午夜电影久久影院| 麻豆精品国产传媒mv男同| 亚洲一二三专区| 亚洲一卡二卡三卡四卡无卡久久| 国产精品久久看| 国产欧美精品一区| 26uuu国产在线精品一区二区| 欧美日韩亚州综合| 欧美日韩一区国产| 色综合久久综合| 色综合天天综合网国产成人综合天 | 成人午夜免费av| 午夜精品在线看| 日本亚洲视频在线| 久久99精品国产91久久来源| 秋霞av亚洲一区二区三| 日本美女一区二区三区| 91亚洲永久精品| 在线亚洲一区二区| 欧美一区二区三区色| 久久综合久久鬼色| 一级中文字幕一区二区| 日本最新不卡在线| 国产成都精品91一区二区三| 91免费小视频| 精品人伦一区二区色婷婷| 亚洲三级在线播放| 国产尤物一区二区| 欧美三级视频在线| 中文在线一区二区| 日本不卡中文字幕| 91在线看国产| 日韩免费高清视频| 一区二区三区在线视频播放| 久久国产精品99精品国产 | 亚洲主播在线观看| 国产日产欧产精品推荐色| 三级欧美在线一区| 日本久久电影网| 国产精品美女久久久久久久| 久久99日本精品| 91精品久久久久久久91蜜桃| 亚洲精品视频一区| 99精品视频中文字幕| 久久久久9999亚洲精品| 日韩和欧美的一区| 91精品国产综合久久久久久漫画| 最新高清无码专区| 99久久久国产精品免费蜜臀| 久久精品一区二区三区不卡| 日韩av一区二区三区| 欧美肥妇bbw| 免费成人在线播放| 精品av综合导航| 成人精品鲁一区一区二区| 综合久久国产九一剧情麻豆| 99精品欧美一区二区三区小说 | 亚洲欧美国产三级| 中文字幕乱码一区二区免费| 国产精品18久久久久久久久 | 日韩一级大片在线| 亚洲电影激情视频网站| av在线不卡电影| 亚洲成人黄色小说| 精品福利一二区| 91福利在线导航| 日本不卡中文字幕| 综合网在线视频| 久久免费视频色| 欧美制服丝袜第一页| 日产精品久久久久久久性色| 国产精品热久久久久夜色精品三区 | 91视频免费看| 免费在线观看一区|