前言
為了讓程式更有彈性, 在某些情況下會需要在 runtime 的時候建立 struct 的實例, 透過使用 Go Lang 內建的 reflect 套件, 就可以輕鬆地動態產生實例並且賦值以實作一個Copy的函式為例
func Copy(i interface{}) interface{}{
objType := reflect.TypeOf(i)
objVal := reflect.ValueOf(i)
newObjValPtr := reflect.New(objType)
newObjValPtr.Elem().Set(objVal)
return newObjValPtr.Elem().Interface()
}
首先呼叫
reflect.TypeOf
取得某個型態的相關結構資訊objType := reflect.TypeOf(i)
Note以Go Lang的設計原則來說, 每個變數都會有一組資訊用來記錄值以及型態的資訊
(value, type )
reflect.ValueOf
傳回一個 Value 的實例(Value 是定義在 reflect 套件裡的結構, 提供了一些方法可以取得實際的值)
objVal := reflect.ValueOf(i)
reflect.New
來產生一個空的 Value 實例newObjValPtr := reflect.New(objType)
若要對這個空 Value 賦值, 必須使用
.Elem
取得 newObjValPtr 的實際值指向的本體後, 才能以.Set
賦值newObjValPtr.Elem().Set(objVal)
NoteValue的值若是一個指標, 必須透過 Elem() 方法才能取得目標值
.Interface
以 Interface{}的形態輸出newObjValPtr.Elem().Interface()
實驗1.func Main(){
page := Paging{
Offset: 1,
Size: 10,
}
newPage := Copy(page)
fmt.Println(newPage) // {10, 1}
}
實驗2.func Main(){
page := &Paging{
Offset: 1,
Size: 10,
}
newPage := Copy(page)
fmt.Println(newPage) // &{10, 1}
}
若 Copy 傳入的參數是個結構變數但卻要返回一個指標的結構變數可以在輸出時呼叫
.Addr
來獲得指標newObjValPtr.Elem().Addr().Interface()
實驗3.func Main(){
page := Paging{
Offset: 1,
Size: 10,
}
newPage := Copy(page)
fmt.Println(newPage) // &{10, 1}
}
留言
張貼留言