美文网首页工作生活
(十四)golang unsafe.Pointer

(十四)golang unsafe.Pointer

作者: 杰克慢 | 来源:发表于2019-07-01 14:53 被阅读0次

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

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        u := string(32)
        i := int32(1)
        fmt.Println(&u, &i) // 打印出地址
        p := &i             // p 的类型是 *int32
        p := &u             // &u的类型是 *string,于 p 的类型不同,不能赋值 会报错
        p := (*string)(&u)  // 这种类型强制转换也是无效的 会报错
        fmt.Println(p)
    }
    

    针对刚刚的问题,我们可以采用 unsafe 标准库来解决。在官方的诠释中,有如下概述:
    围绕 Go 程序内存安全及类型的操作
    很可能会是不可移植的
    不受 Go 1 兼容性指南的保护
    简单来讲就是,不怎么推荐你使用

    package main
    
    import (
        "fmt"
        "unsafe"
    )
    
    func main() {
        u := string(32)
        i := int32(1)
        fmt.Println(&u, &i) 
        p := &u            
        p = (*string)(unsafe.Pointer(&i))
        fmt.Println(p)
    }
    
    package main
    
    import (
        "fmt"
        "unsafe"
    )
    
    type Num struct {
        i string
        j int64
    }
    
    func main() {
        n := Num{i: "test", j: 1}
        nPointer := unsafe.Pointer(&n)
    
        niPointer := (*string)(unsafe.Pointer(nPointer))
        *niPointer = "dr"
    
        njPointer := (*int64)(unsafe.Pointer(uintptr(nPointer) + unsafe.Offsetof(n.j)))
        *njPointer = 2
    
        fmt.Printf("n.i: %s, n.j: %d", n.i, n.j)
    }
    
    

    1、uintptr:uintptr 是 Go 的内置类型。返回无符号整数,可存储一个完整的地址。后续常用于指针运算

    type uintptr uintptr
    

    2、unsafe.Offsetof:返回变量的字节大小,也就是本文用到的偏移量大小。需要注意的是入参 ArbitraryType 表示任意类型,并非定义的 int。它实际作用是一个占位符

    func Offsetof(x ArbitraryType) uintptr
    
     ptr := uintptr(nPointer)
    

    uintptr 类型是不能存储在临时变量中的。因为从 GC 的角度来看,uintptr 类型的临时变量只是一个无符号整数,并不知道它是一个指针地址

    因此当满足一定条件后,ptr 这个临时变量是可能被垃圾回收掉的.

    相关文章

      网友评论

        本文标题:(十四)golang unsafe.Pointer

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