我正在嘗試撰寫遞回遍歷結構并跟蹤指向其所有欄位的指標以進行基本分析(大小、參考數等)的代碼。但是,我遇到了一個問題,我似乎無法獲得反射來給我指向純結構的指標。我以以下代碼為例:
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第二次命中并退出遞回。知道如何使用反射獲取結構的指標嗎?
uj5u.com熱心網友回復:
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 通常用于獲取指向結構欄位或切片元素的指標,以便呼叫需要指標接收器的方法。
uj5u.com熱心網友回復:
如果可能的話,這需要一個值的指標。
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
}
uj5u.com熱心網友回復:
正如您所提到的,您的代碼在這部分失敗了
fooVal := reflect.ValueOf(fooObj)
_ = fooVal.Addr().Pointer() // fails
_ = fooVal.Pointer() // fails
在foostructdata中不是指標值。
type foo struct {
A *bar
data []int8
}
您正在嘗試呼叫非指標型別,導致錯誤reflect.Value.Addr().Pointer()。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
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/455065.html
上一篇:這個numba函式的錯誤是什么?
