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

2019-10-07  本文已影响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
上一篇下一篇

猜你喜欢

热点阅读