美文网首页
golang的指针类型,unsafe.Pointer类型和uin

golang的指针类型,unsafe.Pointer类型和uin

作者: 舒小贱 | 来源:发表于2020-05-02 22:52 被阅读0次

一,区别

1,指针类型

golang支持指针类型,指针类型的变量存的是一个内存地址,这个地址指向的内存空间存的才是一个具体的值。

比如int,int32,A(自定义结构体类型),string等,都是指针类型。

golang的指针类型和c/c++的指针类型基本一样,但是多了几个限制:

  • 1,int,int32等不同的指针类型不能相互转化.
  • 2,指针类型不支持c/c++这样的指针运算。

2,unsafe.Pointer类型

这个类型比较重要,它是实现定位和读写的内存的基础。go runtime大量使用它。官方解释是:

Pointer represents a pointer to an arbitrary type. There are four special operations available for type Pointer that are not available for other types:
- A pointer value of any type can be converted to a Pointer.
- A Pointer can be converted to a pointer value of any type.
- A uintptr can be converted to a Pointer.
- A Pointer can be converted to a uintptr.

根据官方解释,unsafe.Pointer类型可以指代上面说的任意一种指针类型。

  • unsafe.Pointer类型可以和任意指针类型互转
  • unsafe.Pointer类型可以和uintptr类型(后面介绍)互转

3, uintprt类型

uintptr是golang的内置类型。是能存储指针的整形。

type uintptr uintptr 

在64位平台上,底层的数据类型是:

typedef unsigned long long int  uint64;
typedef uint64          uintptr;

uintptr的用处也很大:

  • uintptr可以和unsafe.Pointer类型互转(上面提到过)。
  • uintptr可以做指针运算,这一点有时候很重要,但是依赖平台,同一类型变量在不同的平台占用的存储空间大小不一样,在用uintptr做指针运算的时候,偏移量也会相应的不一样(后面有例子说明)。

二,使用

上面介绍了指针,unsafe.Pointer和uintptr这三种类型,看起来这三种类型存的都是变量的内存地址,那为什么要有三种呢?关键就在于:

  • unsafe.Pointer类型可以和另外两种类型互转
  • uintptr类型可以做指针运算
  • 指针类型可以方便的取变量值

把这三者结合起来,我们就可以方便的对变量做修改:

type MyStruct struct {
    i int
    j int
}

func myFunction(ms *MyStruct) {
    ptr := unsafe.Pointer(ms)
    for i := 0; i < 2; i++ {
        c := (*int)(unsafe.Pointer((uintptr(ptr) + uintptr(8*i))))
        *c += i + 1
        fmt.Printf("[%p] %d\n", c, *c)
    }
}

func main() {
    a := &MyStruct{i: 40, j: 50}
    myFunction(a)
    fmt.Printf("[%p] %v\n", a, a)
}

这个例子是分析golang结构体在内存中的布局写的,*MyStruct是指针类型,我们想对i和j两个成员的值做修改。

为了拿到j的内存地址,先用uintptr(unsafe.Pointer(*MyStruct))来获取i的内存地址,然后用uintptr+8这种地址运算来得到成员j的内存地址,这要基于两点保证:

  • 1,golang的struct结构体数据在内存中是一整块连续的。
  • 2,+8是int类型在64位操作系统上占用8字节,同样的类型在不同的操作系统上占用内存空间是不一样的。

从这个例子我们可以看到unsafe.Pointer和uintptr和指针的配合使用可以给我们对运行时的代码做一些非常灵活的操作。

三,参考

1,你不知道的Go unsafe.Pointer uintptr原理和玩法
2,golang的函数调用

相关文章

  • golang的指针类型,unsafe.Pointer类型和uin

    一,区别 1,指针类型 golang支持指针类型,指针类型的变量存的是一个内存地址,这个地址指向的内存空间存的才是...

  • 【golang】unsafe笔记

    unsafe.Pointer 作用:用于各种指针相互转换的桥梁 任何类型的指针和unsafe.Pointer可以相...

  • Golang学习 - unsafe 包

    指针类型: *类型:普通指针,用于传递对象地址,不能进行指针运算。 unsafe.Pointer:通用指针类型,用...

  • golang中string slice array转换 byte

    unsafe 任何类型的指针和 unsafe.Pointer 可以相互转换。 uintptr 类型和 unsafe...

  • Golang基础(三)——复杂类型

    Golang基础(三)——复杂类型 @([07] golang)[Go总结] [TOC] 指针 定义 指针变量可以...

  • golang的值类型,指针类型和引用类型&值传递&指针传递

    一,变量类型 变量分为值类型,指针类型和引用类型。以如下变量定义和赋值语句为例: output: 值类型变量a,值...

  • (十四)golang unsafe.Pointer

    golang 的指针Go语言是个强类型语言。也就是说Go对类型要求严格,不同类型不能进行赋值操作。指针也是具有明确...

  • 初级问题

    1、Golang make和new的区别 makenew返回值返回对应的引用类型分配零值填充的T类型,并返回指针 ...

  • golang实战笔记

    golang实战笔记 一、集合类型 1.值指针和引用类型a、go语言变量持有相应的值,列外:通道、函数、方法、映射...

  • 指针小解

    原文链接指针的类型分为指针本身的类型和指针所指向的类型 int *ptr; //指针的类型是int *, 指针...

网友评论

      本文标题:golang的指针类型,unsafe.Pointer类型和uin

      本文链接:https://www.haomeiwen.com/subject/mzblghtx.html