7

golang 三种指针类型具体类型的指针、unsafe.Pointer、uintptr作用

 2 years ago
source link: https://studygolang.com/articles/35041
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

原博客地址

golang的三种指针类型

  1. 具体类型的指针,如int、string等
  2. unsafe.Pointer,在unsafe下面,任何具体类型的指针都能转化成Pointer,可以实现不同类型的指针的互相转化,充当桥梁的作用
  3. uintptr,golang源码的注释为能存储任何类型的指针的类型,uintptr可以进行指针计算,然后对对应的指针地址的变量进行复制,完成一些黑魔法

具体类型的指针

具体类型的指针,平时开发使用的很多,不同指针类型不能进行转化,主要用作参数

unsafe.Pointer

开发者开发过程使用的很少,在golang源码中使用的比较多,可以充当桥梁,实现不同类型的指针的转换

  1. 任何类型的指针可以转换成Pointer
  2. Pointer可以转换成任何类型的指针
  3. uintptr可以转换成Pointer
  4. Pointer可以转换成uintptr

    uintptr

    开发者开发过程使用的很少,在golang源码中使用的比较多,实现指针的计算

实现struct里面的未导出的变量的赋值
Demo的内存存储结构: 在这里插入图片描述

demo/demo.go

type Demo struct {
    a int32
    b byte
    c int64
}

main.go 打印出来为 &{1 97 2}

d := new(demo.Demo)

    // 获取a的地址并转化为int32,然后进行赋值
    *(*int32)(unsafe.Pointer(d)) = 1
    // 获取b的地址,需要加上int32的地址,然后进行赋值
    *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(d)) + unsafe.Sizeof(int32(0)))) = 'a'
    // 获取c的地址,需要加上int64的大小,因为进行了内存对齐,后续会弄一篇博客阐述内存对齐,大致就是按照最大的内存大小的内存对齐,下面就是int64的大小对齐,如下面的就是按照int64对齐,因为int32加上byte为5byte,比int64的8byte小,就只需要一个int64就行
    *(*int64)(unsafe.Pointer(uintptr(unsafe.Pointer(d)) + unsafe.Sizeof(int64(0)))) = 2

    fmt.Println(d)

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK