欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go unsafe 包的使用詳解

 更新時(shí)間:2020年01月20日 08:27:48   作者:大二小的寶  
這篇文章主要介紹了Go unsafe 包的使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

unsafe包

golang是一種靜態(tài)的強(qiáng)類(lèi)型的語(yǔ)言,所有的類(lèi)型都是不能隨意轉(zhuǎn)換的,Go語(yǔ)言是不允許兩個(gè)指針類(lèi)型進(jìn)行轉(zhuǎn)換的。go官方是不推薦使用unsafe的操作因?yàn)樗遣话踩?,它繞過(guò)了golang的內(nèi)存安全原則,容易使你的程序出現(xiàn)莫名其妙的問(wèn)題,不利于程序的擴(kuò)展與維護(hù)。但是在很多地方卻是很實(shí)用。在一些go底層的包中unsafe包被很頻繁的使用。

unsafe 定義

package unsafe
//ArbitraryType僅用于文檔目的,實(shí)際上并不是unsafe包的一部分,它表示任意Go表達(dá)式的類(lèi)型。
type ArbitraryType int
//任意類(lèi)型的指針,類(lèi)似于C的*void
type Pointer *ArbitraryType
//確定結(jié)構(gòu)在內(nèi)存中占用的確切大小
func Sizeof(x ArbitraryType) uintptr
//返回結(jié)構(gòu)體中某個(gè)field的偏移量
func Offsetof(x ArbitraryType) uintptr
//返回結(jié)構(gòu)體中某個(gè)field的對(duì)其值(字節(jié)對(duì)齊的原因)
func Alignof(x ArbitraryType) uintptr

官方中定義了四個(gè)描述:

  1. 任何類(lèi)型的指針都可以被轉(zhuǎn)化為Pointer
  2. Pointer可以被轉(zhuǎn)化為任何類(lèi)型的指針
  3. uintptr可以被轉(zhuǎn)化為Pointer
  4. Pointer可以被轉(zhuǎn)化為uintptr

unsafe的使用

類(lèi)型轉(zhuǎn)換

使用unsafe可以實(shí)現(xiàn)類(lèi)型的轉(zhuǎn)換,下面的例子可以看到i是一個(gè)int類(lèi)型,使用unsafe.Pointer轉(zhuǎn)換成float64并且還修改了指針對(duì)應(yīng)的值。

func main() {
  i := 10
  ip := &i

  fp := (*float64)(unsafe.Pointer(ip))

  *fp = *fp * 3

  fmt.Println(i)
}

// 結(jié)果: 30

但是使用起來(lái)要十分的小心,如果使用不當(dāng)會(huì)引發(fā)錯(cuò)誤??梢耘e一個(gè)例子:

func main() {
  i := 10
  ip := &i

  fp := (*string)(unsafe.Pointer(ip))

  *fp = "a"

  fmt.Println(i)
  // 結(jié)果:19678090
}

上面的誤操作就是把int類(lèi)型轉(zhuǎn)成了string,并且修改了值導(dǎo)致結(jié)果出現(xiàn)了錯(cuò)誤,并且這種錯(cuò)誤

根據(jù)位移獲取、修改對(duì)象的字段

利用unsafe的Pointer和Offsetof函數(shù),可以獲取對(duì)象的屬性,并且可以修改對(duì)象的屬性

type Student struct {
  Name string
  Age int
}

func main() {
  s := Student{}
  s.Name = "Peter"
  s.Age = 33

  pStudent := unsafe.Pointer(&s)
  // 整個(gè)對(duì)象轉(zhuǎn)換成指針,默認(rèn)是獲取第一個(gè)屬性
  name := (*string)(unsafe.Pointer(pStudent))
  fmt.Println("name:", *name)
  // 利用Offsetof獲取age屬性的偏移量獲取屬性
  age := (*int)(unsafe.Pointer(uintptr(pStudent) + unsafe.Offsetof(s.Age)))
  fmt.Println("age:", *age)
  
  // 修改指針的值
  *name = "Mary"
  *age = 20
  fmt.Println(s)
}

獲取私有變量

可以通過(guò)unsafe獲取私有變量的值,也可以修改值。這個(gè)操作跟上面的獲取值是一樣的簡(jiǎn)單的例子如下:

type Teacher struct {
  name string
  age int
}

func main() {
  t := Teacher{"ttt", 20}

  pt := unsafe.Pointer(&t)
  name := (*string)(unsafe.Pointer(pt))
  fmt.Println("name:", *name)
}

根據(jù)sizeof函數(shù)獲取、修改

利用unsafe中的sizeof函數(shù)獲取數(shù)組的值

func main() {
  array := []int{0, 1, -2, 3, 4}
  pointer := &array[0]
  fmt.Print(*pointer, " ")
  memoryAddress := uintptr(unsafe.Pointer(pointer)) + unsafe.Sizeof(array[0])
  for i := 0; i < len(array)-1; i++ {
    pointer = (*int)(unsafe.Pointer(memoryAddress))
    fmt.Print(*pointer, " ")
    memoryAddress = uintptr(unsafe.Pointer(pointer)) + unsafe.Sizeof(array[0])
  }
}

結(jié)果:0 1 -2 3 4

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • windows下安裝make及使用makefile文件

    windows下安裝make及使用makefile文件

    這篇文章主要為大家介紹了windows下安裝make及使用makefile文件方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • 詳解如何在Go語(yǔ)言中生成隨機(jī)種子

    詳解如何在Go語(yǔ)言中生成隨機(jī)種子

    這篇文章主要為大家詳細(xì)介紹了如何在Go語(yǔ)言中生成隨機(jī)種子,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下
    2024-04-04
  • 詳解golang中的method

    詳解golang中的method

    這篇文章主要介紹了golang中的method的相關(guān)資料,幫助大家更好的理解和使用golang,感興趣的朋友可以了解下
    2021-01-01
  • 解析Golang和Java的優(yōu)勢(shì)與劣勢(shì)

    解析Golang和Java的優(yōu)勢(shì)與劣勢(shì)

    Golang和Java是兩種流行的編程語(yǔ)言,它們?cè)诤芏喾矫嬗兄嗨浦?但也存在一些重要的區(qū)別,本文將對(duì)Golang和Java進(jìn)行對(duì)比,探討它們的特點(diǎn)和適用場(chǎng)景,需要的朋友可以參考下
    2023-10-10
  • golang中new與make的區(qū)別講解

    golang中new與make的區(qū)別講解

    new只能開(kāi)辟單個(gè)空間,不能為引用類(lèi)型開(kāi)辟多個(gè)空間,并且new是對(duì)類(lèi)型進(jìn)行內(nèi)存的開(kāi)辟,返回一個(gè)指向該內(nèi)存空間的指針類(lèi)型,如果使用new去初始化引用數(shù)據(jù)類(lèi)型,不是很合適(當(dāng)然,new一個(gè)對(duì)象還是可以的),因此就需要用到另一個(gè)內(nèi)置函數(shù)make,需要的朋友可以參考下
    2023-01-01
  • Golang拾遺之實(shí)現(xiàn)一個(gè)不可復(fù)制類(lèi)型詳解

    Golang拾遺之實(shí)現(xiàn)一個(gè)不可復(fù)制類(lèi)型詳解

    在這篇文章中我們將實(shí)現(xiàn)一個(gè)無(wú)法被復(fù)制的類(lèi)型,順便加深對(duì)引用類(lèi)型、值傳遞以及指針的理解。文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2023-02-02
  • Golang的循環(huán)語(yǔ)句和循環(huán)控制語(yǔ)句詳解

    Golang的循環(huán)語(yǔ)句和循環(huán)控制語(yǔ)句詳解

    循環(huán)語(yǔ)句為了簡(jiǎn)化程序中有規(guī)律的重復(fù)性操作,需要用到循環(huán)語(yǔ)句,和其他大多數(shù)編程語(yǔ)言一樣,GO的循環(huán)語(yǔ)句有for循環(huán),不同的是沒(méi)有while循環(huán),而循環(huán)控制語(yǔ)句可以改變循環(huán)語(yǔ)句的執(zhí)行過(guò)程,下面給大家介紹下go循環(huán)語(yǔ)句和循環(huán)控制語(yǔ)句的相關(guān)知識(shí),一起看看吧
    2021-11-11
  • golang去除多余的空格與換行符示例代碼

    golang去除多余的空格與換行符示例代碼

    Golang是一種強(qiáng)大的編程語(yǔ)言,提供了豐富的字符串處理功能,這篇文章主要給大家介紹了關(guān)于golang去除多余的空格與換行符的相關(guān)資料,需要的朋友可以參考下
    2023-10-10
  • go-cqhttp權(quán)限管理系統(tǒng)的實(shí)現(xiàn)代碼

    go-cqhttp權(quán)限管理系統(tǒng)的實(shí)現(xiàn)代碼

    這篇文章主要介紹了go-cqhttp權(quán)限管理,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • 簡(jiǎn)單聊聊Go語(yǔ)言中空結(jié)構(gòu)體和空字符串的特殊之處

    簡(jiǎn)單聊聊Go語(yǔ)言中空結(jié)構(gòu)體和空字符串的特殊之處

    在日常的編程過(guò)程中,大家應(yīng)該經(jīng)常能遇到各種”空“吧,比如空指針、空結(jié)構(gòu)體、空字符串等,本文就以?Go?語(yǔ)言為例,一起來(lái)看看空結(jié)構(gòu)體和空字符串在?Go?語(yǔ)言中的特殊之處吧
    2024-03-03

最新評(píng)論