unsafe包的應用與字節對齊

以一個例子來講明:ui

//misc.go指針

package misc
 
type S struct {
        i int32
        k int8
        j int64
}

//main.gocode

func main() {
        s := new(misc.S)
        //經過unsafe Pointer給未導出的字段賦值
        //由於字節對齊,內存中實際分配
        //int32|int8|  int64 |
        //|xxxx|x---|xxxxxxxx|
        p := (*int32)(unsafe.Pointer(s))
        *p = int32(10)
        // 1.unsafe Pointer和uintptr能夠互相轉換
        // 2.unsafe Pointer和其餘類型的指針能夠互相轉換
        // 3.unsafe Pointer不能進行指針運算而uintptr能
        p1 := (*int8)(unsafe.Pointer(uintptr(unsafe.Pointer(s)) + unsafe.Alignof(int32(0))))//偏移4
        *p1 = int8(-128)
        p2 := (*int64)(unsafe.Pointer(uintptr(unsafe.Pointer(s)) + unsafe.Alignof(s)))//偏移8
        *p2 = int64(128)
        fmt.Println(s)//&{10 -128 128}
        fmt.Println(unsafe.Sizeof(*s))//16 由於字節對齊的緣故不是13
        fmt.Println(unsafe.Sizeof(s))//8 s是指針,在64位系統裏指針佔8個字節,指針就是內存地址,大小跟系統有關跟語言無關
        fmt.Println(unsafe.Alignof(s))//8 Alignof返回該類型的對齊值,struct的對齊值是成員類型對齊值的最大值
}

此例子基於struct在內存中是連續的,而且知道S的結構。以上僅爲記錄unsafe包的基本使用方式和字節對齊是怎麼回事,以避免忘了,非實際應用場景。內存

相關文章
相關標籤/搜索