美文网首页
go 利用unsafe.Pointer和uintptr 给私有变

go 利用unsafe.Pointer和uintptr 给私有变

作者: 夏依旧微凉啊 | 来源:发表于2019-10-07 16:10 被阅读0次
  • 定义类型 及访问是有变量的方法
package p

import "fmt"

type V struct {
    i int
    j string
    k float64
}

// 此处不用V,否则this 会是调用者的复制,而不是原对象
func (this *V) PutIPtr() {
    fmt.Println(fmt.Sprintf("v.i ptr:%p", &this.i))
}

func (this V) PutI() {
    fmt.Println(fmt.Sprintf("V.i:%d", this.i))
}

func (this V) PutJ() {
    fmt.Println(fmt.Sprintf("V.j:%s", this.j))
}

func (this V) PutK() {
    fmt.Println(fmt.Sprintf("V.j:%f", this.k))
}

  • 在外面赋值
package main

import (
    "fmt"
    "myself/go-ptr/p"
    "unsafe"
)

func main() {
    // 初始化内存,返回p.V类型的一个指针
    v := new(p.V)

    // v 的地址也是v.i的地址
    fmt.Println(fmt.Sprintf("new ptr:%p", v))
    v.PutIPtr()
    i := (*int)(unsafe.Pointer(v))
    *i = 66

    // uintptr(unsafe.Sizeof(int(2))) 获取int类型的指针长度
    // v 指针地址的基础上加上int类型长度,为v.j的地址
    j := (*string)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + uintptr(unsafe.Sizeof(int(2)))))
    *j = "this is string"
    k := (*float64)(unsafe.Pointer(uintptr(unsafe.Pointer(j)) + uintptr(unsafe.Sizeof(string("22")))))
    *k = 99
    v.PutI()
    v.PutJ()
    v.PutK()
}

*运行结果

new ptr:0xc000004480
v.i ptr:0xc000004480
V.i:66
V.j:this is string
V.j:99.000000

相关文章

网友评论

      本文标题:go 利用unsafe.Pointer和uintptr 给私有变

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