2017-08-30 83 views
0

我得到一個變量的地址,該類型轉換爲unsafe.Pointer,並且我得到了它的類型名稱,例如「int64」或「struct main.Person」或其他人。如何將unsafe.Pointer轉換爲reflect.Type或reflect.Value

看到代碼:

package main 

type Person struct { 
    Name string 
    Age int 
} 

p := Person{"john", 25} 
addr := unsafe.Pointer(&p) 
typName := "struct main.Person" 

typ := module.TypeOfByAddr(addr, typName) 

// now, I got variable addr, typName in func module.TypeOfByAddr 
// how can I get reflect.Type of variable p without using package.Person to convert? 

package module 

func TypeOfByAddr(addr unsafe.Pointer, typName string) reflect.Type { 
    // how to convert addr to reflect.Type? 
} 
+0

我不認爲這是可能的。無論如何,我不禁感到你正在試圖做一些可怕的,可怕的,錯誤的事情。爲什麼在這個世界上你會需要以這種方式濫用類型系統? –

+0

你試圖完成什麼?要獲得一些任意Go值的'reflect.Type/Value',你不需要使用'unsafe.Pointer'。 – mkopriva

+0

@MiloChristiansen我想轉儲每個追溯幀中局部變量的所有值和名稱。如果成功,調試將很方便。我可以得到棧幀中每個變量的地址(類型爲uintptr)。 –

回答

1

爲什麼你需要指針獲取類型?所有你需要的是類型名稱。

在Go中,不可能直接從字符串中獲取reflect.Type。該類型必須在某處引用,以便編譯器知道它將包含在內。但是,您可以使用map[string]reflect.Type獲得相同的效果。

如果你的類型是靜態的,只是聲明:

var types = map[string]reflect.Type{ 
    "int64": reflect.TypeOf(int64(0)), 
    "string": reflect.TypeOf(string("")), 
    // ... and so on 
} 

如果您的類型從不同的軟件包動態註冊,可以從init功能,這樣的註冊類型:

var types = make(map[string]reflect.Type) 

func AddType(name string, i interface{}) { 
    if _, ok := types[name]; ok { 
     panic("Type " + name + " registered multiple times") 
    } 
    types[name] = reflect.TypeOf(i) 
} 

// Called somewhere else 

func init() { 
    AddType("struct main.Person", Person{}) 
} 

如果您想要從指針和類型名稱中獲得reflect.Value,可以執行以下操作:

func ValueOfByAddr(addr unsafe.Pointer, typName string) reflect.Value { 
    t, ok := types[typName] 
    if !ok { 
     panic("Unknown type name") 
    } 
    return reflect.NewAt(t, addr) 
} 
+0

酷〜但我怎麼能列出所有類型的運行時?我試圖轉儲所有 本地變量的值和名稱在每個追溯幀。我讀了golang reflect.TypeOf的源代碼,看代碼[reflect.TypeOf](https://github.com/golang/go/blob/master/src/reflect/type.go#L1395), I發現一個指針(unsafe.Pointer)可以轉換爲reflect.Type內部。那麼我可以在用戶運行時嘗試嗎? –

相關問題