前言
為了讓程式更有彈性, 在某些情況下會需要在 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()func Main(){
  page := Paging{
    Offset: 1,
    Size: 10,
  }
  newPage := Copy(page)
  fmt.Println(newPage) // {10, 1}
}func Main(){
  page := &Paging{
    Offset: 1,
    Size: 10,
  }
  newPage := Copy(page)
  fmt.Println(newPage) // &{10, 1}
}可以在輸出時呼叫
.Addr來獲得指標newObjValPtr.Elem().Addr().Interface()func Main(){
  page := Paging{
    Offset: 1,
    Size: 10,
  }
  newPage := Copy(page)
  fmt.Println(newPage) // &{10, 1}
}
留言
張貼留言