经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » PHP » 查看文章
GO反射类实例
来源:cnblogs  作者:smallsha  时间:2021/5/31 9:12:18  对本文有异议

变量的内在机制

类型信息:是静态的元信息,是预先定义好的

值信息:是程序运行过程中动态改变的

反射的使用

获取类型信息:reflect.TypeOf,是静态的

获取值信息:reflect.ValueOf,是动态的

反射获取interface值信息

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. //反射获取interface值信息
  7. func reflect_value(a interface{}) {
  8. v := reflect.ValueOf(a)
  9. fmt.Println(v)
  10. k := v.Kind()
  11. fmt.Println(k)
  12. switch k {
  13. case reflect.Float64:
  14. fmt.Println("a是:", v.Float())
  15. }
  16. }
  17. func main() {
  18. var x float64 = 3.4
  19. reflect_value(x)
  20. }

反射修改值信息

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. //反射修改值
  7. func reflect_set_value(a interface{}) {
  8. v := reflect.ValueOf(a)
  9. k := v.Kind()
  10. switch k {
  11. case reflect.Float64:
  12. // 反射修改值
  13. v.SetFloat(6.9)
  14. fmt.Println("a is ", v.Float())
  15. case reflect.Ptr:
  16. // Elem()获取地址指向的值
  17. v.Elem().SetFloat(7.9)
  18. fmt.Println("case:", v.Elem().Float())
  19. // 地址
  20. fmt.Println(v.Pointer())
  21. }
  22. }
  23. func main() {
  24. var x float64 = 3.4
  25. // 反射认为下面是指针类型,不是float类型
  26. reflect_set_value(&x)
  27. fmt.Println("main:", x)
  28. }

结构体与反射

查看类型、字段和方法

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. // 定义结构体
  7. type User struct {
  8. Id int
  9. Name string
  10. Age int
  11. }
  12. // 绑方法
  13. func (u User) Hello() {
  14. fmt.Println("Hello")
  15. }
  16. // 传入interface{}
  17. func Poni(o interface{}) {
  18. t := reflect.TypeOf(o)
  19. fmt.Println("类型:", t)
  20. fmt.Println("字符串类型:", t.Name())
  21. // 获取值
  22. v := reflect.ValueOf(o)
  23. fmt.Println(v)
  24. // 可以获取所有属性
  25. // 获取结构体字段个数:t.NumField()
  26. for i := 0; i < t.NumField(); i++ {
  27. // 取每个字段
  28. f := t.Field(i)
  29. fmt.Printf("%s : %v", f.Name, f.Type)
  30. // 获取字段的值信息
  31. // Interface():获取字段对应的值
  32. val := v.Field(i).Interface()
  33. fmt.Println("val :", val)
  34. }
  35. fmt.Println("=================方法====================")
  36. for i := 0; i < t.NumMethod(); i++ {
  37. m := t.Method(i)
  38. fmt.Println(m.Name)
  39. fmt.Println(m.Type)
  40. }
  41. }
  42. func main() {
  43. u := User{1, "zs", 20}
  44. Poni(u)
  45. }

查看匿名字段

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. // 定义结构体
  7. type User struct {
  8. Id int
  9. Name string
  10. Age int
  11. }
  12. // 匿名字段
  13. type Boy struct {
  14. User
  15. Addr string
  16. }
  17. func main() {
  18. m := Boy{User{1, "zs", 20}, "bj"}
  19. t := reflect.TypeOf(m)
  20. fmt.Println(t)
  21. // Anonymous:匿名
  22. fmt.Printf("%#v\n", t.Field(0))
  23. // 值信息
  24. fmt.Printf("%#v\n", reflect.ValueOf(m).Field(0))
  25. }

修改结构体的值

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. // 定义结构体
  7. type User struct {
  8. Id int
  9. Name string
  10. Age int
  11. }
  12. // 修改结构体值
  13. func SetValue(o interface{}) {
  14. v := reflect.ValueOf(o)
  15. // 获取指针指向的元素
  16. v = v.Elem()
  17. // 取字段
  18. f := v.FieldByName("Name")
  19. if f.Kind() == reflect.String {
  20. f.SetString("kuteng")
  21. }
  22. }
  23. func main() {
  24. u := User{1, "5lmh.com", 20}
  25. SetValue(&u)
  26. fmt.Println(u)
  27. }

调用方法

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. // 定义结构体
  7. type User struct {
  8. Id int
  9. Name string
  10. Age int
  11. }
  12. func (u User) Hello(name string) {
  13. fmt.Println("Hello:", name)
  14. }
  15. func main() {
  16. u := User{1, "5lmh.com", 20}
  17. v := reflect.ValueOf(u)
  18. // 获取方法
  19. m := v.MethodByName("Hello")
  20. // 构建一些参数
  21. args := []reflect.Value{reflect.ValueOf("6666")}
  22. // 没参数的情况下:var args2 []reflect.Value
  23. // 调用方法,需要传入方法的参数
  24. m.Call(args)
  25. }

获取字段的tag

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. type Student struct {
  7. Name string `json:"name1" db:"name2"`
  8. }
  9. func main() {
  10. var s Student
  11. v := reflect.ValueOf(&s)
  12. // 类型
  13. t := v.Type()
  14. // 获取字段
  15. f := t.Elem().Field(0)
  16. fmt.Println(f.Tag.Get("json"))
  17. fmt.Println(f.Tag.Get("db"))
  18. }

实例

方法

  1. package common
  2. import (
  3. "errors"
  4. "reflect"
  5. "strconv"
  6. "time"
  7. )
  8. //根据结构体中sql标签映射数据到结构体中并且转换类型
  9. func DataToStructByTagSql(data map[string]string, obj interface{}) {
  10. objValue := reflect.ValueOf(obj).Elem()
  11. for i := 0; i < objValue.NumField(); i++ {
  12. //获取sql对应的值
  13. value := data[objValue.Type().Field(i).Tag.Get("sql")]
  14. //获取对应字段的名称
  15. name := objValue.Type().Field(i).Name
  16. //获取对应字段类型
  17. structFieldType := objValue.Field(i).Type()
  18. //获取变量类型,也可以直接写"string类型"
  19. val := reflect.ValueOf(value)
  20. var err error
  21. if structFieldType != val.Type() {
  22. //类型转换
  23. val, err = TypeConversion(value, structFieldType.Name()) //类型转换
  24. if err != nil {
  25. }
  26. }
  27. //设置类型值
  28. objValue.FieldByName(name).Set(val)
  29. }
  30. }
  31. //类型转换
  32. func TypeConversion(value string, ntype string) (reflect.Value, error) {
  33. if ntype == "string" {
  34. return reflect.ValueOf(value), nil
  35. } else if ntype == "time.Time" {
  36. t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
  37. return reflect.ValueOf(t), err
  38. } else if ntype == "Time" {
  39. t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
  40. return reflect.ValueOf(t), err
  41. } else if ntype == "int" {
  42. i, err := strconv.Atoi(value)
  43. return reflect.ValueOf(i), err
  44. } else if ntype == "int8" {
  45. i, err := strconv.ParseInt(value, 10, 64)
  46. return reflect.ValueOf(int8(i)), err
  47. } else if ntype == "int32" {
  48. i, err := strconv.ParseInt(value, 10, 64)
  49. return reflect.ValueOf(int64(i)), err
  50. } else if ntype == "int64" {
  51. i, err := strconv.ParseInt(value, 10, 64)
  52. return reflect.ValueOf(i), err
  53. } else if ntype == "float32" {
  54. i, err := strconv.ParseFloat(value, 64)
  55. return reflect.ValueOf(float32(i)), err
  56. } else if ntype == "float64" {
  57. i, err := strconv.ParseFloat(value, 64)
  58. return reflect.ValueOf(i), err
  59. }
  60. //else if .......增加其他一些类型的转换
  61. return reflect.ValueOf(value), errors.New("未知的类型:" + ntype)
  62. }

调用

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/student/1129/common"
  5. )
  6. //Product Product定义一个结构体
  7. type Product struct {
  8. ID int64 `json:"id" sql:"id"`
  9. ProductClass string `json:"ProductClass" sql:"ProductClass"`
  10. ProductName string `json:"ProductName" sql:"productName"`
  11. ProductNum int64 `json:"ProductNum" sql:"productNum"`
  12. ProductImage string `json:"ProductImage" sql:"productImage"`
  13. ProductURL string `json:"ProductUrl" sql:"productUrl" `
  14. }
  15. func main() {
  16. //这块是模拟mysql获取单条的数据反射到结构体
  17. data := map[string]string{"id": "1", "ProductClass": "blog", "productName": "5lmh.com", "productNum": "40", "productImage": "http://www.5lmh.com/", "productUrl": "http://www.5lmh.com/"}
  18. productResult := &Product{}
  19. common.DataToStructByTagSql(data, productResult)
  20. fmt.Println(*productResult)
  21. //这块是模拟mysql获取所有的数据反射到结构体
  22. Alldata := []map[string]string{
  23. {"id": "1", "ProductClass": "blog", "productName": "5lmh.com", "productNum": "40", "productImage": "http://www.5lmh.com/", "productUrl": "http://www.5lmh.com/"},
  24. {"id": "2", "ProductClass": "blog", "productName": "5lmh.com", "productNum": "40", "productImage": "http://www.5lmh.com/", "productUrl": "http://www.5lmh.com/"},
  25. }
  26. var productArray []*Product
  27. for _, v := range Alldata {
  28. Allproduct := &Product{}
  29. common.DataToStructByTagSql(v, Allproduct)
  30. productArray = append(productArray, Allproduct)
  31. }
  32. for _, vv := range productArray {
  33. fmt.Println(vv)
  34. }
  35. }

原文链接:http://www.cnblogs.com/smallsha/p/14804872.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号