2017-03-28 16 views
1

我使用反射爲我建立一個庫,但有件事情我不理解reflect.Newreflect.New返回<nil>代替初始化結構

type A struct { 
    A int 
    B string 
} 

func main() { 

    real := new(A) 
    reflected := reflect.New(reflect.TypeOf(real)).Elem().Interface() 
    fmt.Println(real) 
    fmt.Println(reflected) 
} 

給出:

$ go run *go 
&{0 } 
<nil> 

是不是reflect.New應該返回&{0 }嗎? (Runnable Version

最後,我希望能夠遍歷反射結構的字段(reflected.NumField()reflected.NumField undefined (type interface {} is interface with no methods)),並使用SetIntSetString等。

感謝,

回答

5

你,當你創建了real變量,它返回一個指針使用內建new()功能! real的類型是*A,而不是A!這是混亂的根源。

reflect.New()返回一個指向給定類型(歸零)的值(包含在reflect.Value中)。如果您通過A類型,則會返回包裝的*A,A初始化/歸零。如果傳遞的類型*A,你回來一個包裹,*A初始化(零),以及任何指針類型的零值nil

您基本上要求reflect.New()創建指針類型(*A)的新值,並且 - 如前所述 - 其零值爲nil

你必須通過類型A(而不是類型*A)。它的工作原理是這樣的(嘗試在Go Playground):

real := new(A) 
reflected := reflect.New(reflect.TypeOf(real).Elem()).Elem().Interface() 
fmt.Println(real) 
fmt.Println(reflected) 

或像這樣(Go Playground):

real := A{} 
reflected := reflect.New(reflect.TypeOf(real)).Elem().Interface() 
fmt.Println(real) 
fmt.Println(reflected)