反射就是程序可以在運行時檢查變量和值,求出它們的類型。html
reflect包實現運行時反射。golang
建立一個接收任何數據類型任何數值的查詢string:函數
func createQuery(q interface{}) string { }
reflect.Type 表示 interface{} 的具體類型,而 reflect.Value 表示它的具體值。reflect.TypeOf() 和 reflect.ValueOf() 兩個函數能夠分別返回 reflect.Type 和 reflect.Value。spa
Type
表示 interface{}
的實際類型(在這裏是 main.Order
),而 Kind
表示該類型的特定類別(在這裏是 struct
)。code
NumField()
方法返回結構體中字段的數量,而 Field(i int)
方法返回字段 i
的 reflect.Value
。htm
func createQuery(q interface{}) { if reflect.ValueOf(q).Kind() == reflect.Struct { v := reflect.ValueOf(q) fmt.Println("Number of fields", v.NumField()) for i := 0; i < v.NumField(); i++ { fmt.Printf("Field:%d type:%T value:%v\n", i, v.Field(i), v.Field(i)) } } }
Int 和 String 能夠分別取出 reflect.Value 做爲 int64 和 string的值。blog
package main import ( "fmt" "reflect" ) type order struct { ordId int customerId int } type employee struct{ name string id int address string salary int country string } func createQuery(q interface{}){ if reflect.ValueOf(q).Kind() == reflect.Struct { t := reflect.TypeOf(q).Name() query := fmt.Sprintf("insert into %s values(", t) v := reflect.ValueOf(q) for i:=0; i < v.NumField(); i++{ switch v.Field(i).Kind(){ case reflect.Int: if i == 0{ query = fmt.Sprintf("%s%d", query, v.Field(i).Int()) } else { query = fmt.Sprintf("%s, %d", query, v.Field(i).Int()) } case reflect.String: if i==0 { query = fmt.Sprintf("%s\"%s\"", query, v.Field(i).String()) } else { query = fmt.Sprintf("%s, \"%s\"", query, v.Field(i).String()) } default: fmt.Println("Unsupported type") return } } query = fmt.Sprintf("%s)", query) fmt.Println(query) return } fmt.Println("Unsupported type") } func main(){ o := order{ ordId: 44, customerId: 100, } createQuery(o) e := employee{ name: "Wang", address: "HN", country: "CN", id: 10000, salary: 10000, } createQuery(e) i := 100 createQuery(i) } output: insert into order values(44, 100) insert into employee values("Wang", 10000, "HN", 10000, "CN") Unsupported type
參考:教程
1. Go 系列教程 —— 34. 反射get
2. Go基礎之--反射string