亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Golang:使用反射獲取指向結構的指針

Golang:使用反射獲取指向結構的指針

Go
收到一只叮咚 2022-11-23 20:09:31
我正在嘗試編寫遞歸遍歷結構并跟蹤指向其所有字段的指針以進行基本分析(大小、引用數量等)的代碼。但是,我遇到了一個問題,我似乎無法得到反射來給我指向純結構的指針。我以下面的代碼為例:type foo struct {    A    *bar    data []int8}type bar struct {    B       *foo    ptrData *[]float64}func main() {    dataLen := 32    refData := make([]float64, dataLen)    fooObj := foo{data: make([]int8, dataLen)}    barObj := bar{        B:       &fooObj,        ptrData: &refData,    }    fooObj.A = &barObj    fooVal := reflect.ValueOf(fooObj)    _ := fooVal.Addr().Pointer() // fails    _ := fooVal.Pointer() // fails    // More analysis code after this}如果我想穿越fooObj,那就好了,直到我進入barObj,然后我又遇到了fooObj。因為第一次fooObj遇到的指針沒辦法拿到,最后遍歷fooObj了兩次,直到碰到barObj第二次才退出遞歸。知道如何使用反射獲取結構的指針嗎?
查看完整描述

3 回答

?
一只斗牛犬

TA貢獻1784條經驗 獲得超2個贊

package main


import (

    "reflect"

    "fmt"

)


type foo struct {

    A    *bar

    data []int8

}


type bar struct {

    B       *foo

    ptrData *[]float64

}


func main() {

    dataLen := 32

    refData := make([]float64, dataLen)

    

    // allocate here, now value has a pointer

    fooObj := &foo{data: make([]int8, dataLen)} 

    barObj := bar{

        B:       fooObj,

        ptrData: &refData,

    }

    fooObj.A = &barObj


    fooVal := reflect.ValueOf(fooObj)

    fmt.Println(fooVal.Pointer()) // succeeds


    // More analysis code after this

}

Addr 返回一個指針值,表示 v 的地址。如果 CanAddr() 返回 false,它會崩潰。Addr 通常用于獲取指向結構字段或切片元素的指針,以便調用需要指針接收器的方法。


查看完整回答
反對 回復 2022-11-23
?
開滿天機

TA貢獻1786條經驗 獲得超13個贊

如果可能的話,這需要一個值的指針。


package main


import "reflect"

import "fmt"


func main() {

    val := new(int)

    slice := []int{}

    local := 10

    fn := func() {}


    fmt.Println(PointerOf(val))

    fmt.Println(PointerOf(slice))

    fmt.Println(PointerOf(&local))

    fmt.Println(PointerOf(fn))

    fmt.Println(PointerOf(3))

}


func PointerOf(value any) (p uintptr, ok bool) {

    rValue := reflect.ValueOf(value)

    

    if(rValue.Kind() == reflect.Pointer || rValue.Kind() == reflect.Slice || rValue.Kind() == reflect.Func) {

        return rValue.Pointer(), true

    }    


    if(rValue.CanAddr()) {

        return rValue.Addr().Pointer(), true

    }


    return

}


查看完整回答
反對 回復 2022-11-23
?
holdtom

TA貢獻1805條經驗 獲得超10個贊

正如您所提到的,您的代碼在這部分失敗了


fooVal := reflect.ValueOf(fooObj)

_ = fooVal.Addr().Pointer() // fails

_ = fooVal.Pointer() // fails

In foostructdata不是指針值。


type foo struct {

    A    *bar

    data []int8

}

您正在嘗試在非指針類型上調用reflect.Value.Addr().Pointer()and ,從而導致錯誤。reflect.Value.Pointer()


您可以通過檢查類型是否實際上是來防止這種情況ptr


package main


import (

    "reflect"

)


type foo struct {

    A    *bar

    data []int8

}


type bar struct {

    B       *foo

    ptrData *[]float64

}


func main() {

    dataLen := 32

    refData := make([]float64, dataLen)


    fooObj := foo{data: make([]int8, dataLen)}

    barObj := bar{

        B:       &fooObj,

        ptrData: &refData,

    }

    fooObj.A = &barObj


    fooVal := reflect.ValueOf(fooObj)


    if fooVal.Kind().String() == "ptr" {

        _ = fooVal.Addr().Pointer() // ok

        _ = fooVal.Pointer()        // ok


       // More analysis code for pointer types

    } else {

       // More analysis code for non-pointer types

    }

}


查看完整回答
反對 回復 2022-11-23
  • 3 回答
  • 0 關注
  • 300 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號