反射就是程序能够在运行时检查变量和值,求出它们的类型。
reflect包实现运行时反射。
创建一个接收任何数据类型任何数值的查询string:
func createQuery(q interface{}) string { }
reflect.Type 表示 interface{} 的具体类型,而 reflect.Value 表示它的具体值。reflect.TypeOf() 和 reflect.ValueOf() 两个函数可以分别返回 reflect.Type 和 reflect.Value。
Type
表示 interface{}
的实际类型(在这里是 main.Order
),而 Kind
表示该类型的特定类别(在这里是 struct
)。
NumField()
方法返回结构体中字段的数量,而 Field(i int)
方法返回字段 i
的 reflect.Value
。
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 ", i, v.Field(i), v.Field(i)) } } }
Int 和 String 可以分别取出 reflect.Value 作为 int64 和 string的值。
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
参考:
2. Go基础之--反射