這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
reflect包的幾個使用情境:
1. 遍曆結構體欄位名(避免代碼的寫入程式碼)
2. 調用結構體方法(自動對應)
3. 擷取結構體的tag標記的值(json/xml轉換)
4. // @todo更多的使用情境
代碼:
一、$GOPATH/reflectusage/main.go:
// reflect使用情境package mainimport ( "errors" "fmt" "reflect" "reflectusage/config")func main() { // 建立Conf執行個體 conf := config.Conf{} opName := "create" conf.Op = &opName conf.Port = 3308 fmt.Printf("conf.Port=%d\n\n", conf.Port) // 結構資訊 t := reflect.TypeOf(conf) // 值資訊 v := reflect.ValueOf(conf) printStructField(&t) callMethod(&v, "SayOp", []interface{}{" Db"}) // panic: reflect: Call of unexported method //callMethod(&v, "getDbConf", []interface{}{}) getTag(&t, "Op", "json") getTag(&t, "Op", "xml") getTag(&t, "nofield", "json")}// 情境1:遍曆結構體欄位名func printStructField(t *reflect.Type) { fieldNum := (*t).NumField() for i := 0; i < fieldNum; i++ { fmt.Printf("conf's field: %s\n", (*t).Field(i).Name) } fmt.Println("")}// 情境2:調用結構體方法func callMethod(v *reflect.Value, method string, params []interface{}) { // 字串方法調用,且能找到執行個體conf的屬性.Op f := (*v).MethodByName(method) if f.IsValid() { args := make([]reflect.Value, len(params)) for k, param := range params { args[k] = reflect.ValueOf(param) } // 調用 ret := f.Call(args) if ret[0].Kind() == reflect.String { fmt.Printf("%s Called result: %s\n", method, ret[0].String()) } } else { fmt.Println("can't call " + method) } fmt.Println("")}// 情境3:擷取結構體的tag標記func getTag(t *reflect.Type, field string, tagName string) { var ( tagVal string err error ) fieldVal, ok := (*t).FieldByName(field) if ok { tagVal = fieldVal.Tag.Get(tagName) } else { err = errors.New("no field named:" + field) } fmt.Printf("get struct[%s] tag[%s]: %s, error:%v\n", field, tagName, tagVal, err) fmt.Println("")}// @todo更多的使用情境
二、$GOPATH/reflectusage/config/config.go:
package configtype Db struct { Port int Host string pw string}type Conf struct { Op *string `json:"jsonop" xml:"xmlOpName"` Charlist *string Length *int Num *int Output *string Input *string hidden *string Db}func (this Conf) SayOp(subname string) string { return *this.Op + subname}func (this Conf) getDbConf() Db { return this.Db}
三、輸出:
conf.Port=3308conf's field: Opconf's field: Charlistconf's field: Lengthconf's field: Numconf's field: Outputconf's field: Inputconf's field: hiddenconf's field: DbSayOp Called result: create Dbget struct[Op] tag[json]: jsonop, error:<nil>get struct[Op] tag[xml]: xmlOpName, error:<nil>get struct[nofield] tag[json]: , error:no field named:nofield