变量的内在机制

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

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

反射的使用

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

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

反射获取interface值信息

package main

import (
"fmt"
"reflect"
) //反射获取interface值信息 func reflect_value(a interface{}) {
v := reflect.ValueOf(a)
fmt.Println(v)
k := v.Kind()
fmt.Println(k)
switch k {
case reflect.Float64:
fmt.Println("a是:", v.Float())
}
} func main() {
var x float64 = 3.4
reflect_value(x)
}

反射修改值信息

package main

import (
"fmt"
"reflect"
) //反射修改值
func reflect_set_value(a interface{}) {
v := reflect.ValueOf(a)
k := v.Kind()
switch k {
case reflect.Float64:
// 反射修改值
v.SetFloat(6.9)
fmt.Println("a is ", v.Float())
case reflect.Ptr:
// Elem()获取地址指向的值
v.Elem().SetFloat(7.9)
fmt.Println("case:", v.Elem().Float())
// 地址
fmt.Println(v.Pointer())
}
} func main() {
var x float64 = 3.4
// 反射认为下面是指针类型,不是float类型
reflect_set_value(&x)
fmt.Println("main:", x)
}

结构体与反射

查看类型、字段和方法

package main

import (
"fmt"
"reflect"
) // 定义结构体
type User struct {
Id int
Name string
Age int
} // 绑方法
func (u User) Hello() {
fmt.Println("Hello")
} // 传入interface{}
func Poni(o interface{}) {
t := reflect.TypeOf(o)
fmt.Println("类型:", t)
fmt.Println("字符串类型:", t.Name())
// 获取值
v := reflect.ValueOf(o)
fmt.Println(v)
// 可以获取所有属性
// 获取结构体字段个数:t.NumField()
for i := 0; i < t.NumField(); i++ {
// 取每个字段
f := t.Field(i)
fmt.Printf("%s : %v", f.Name, f.Type)
// 获取字段的值信息
// Interface():获取字段对应的值
val := v.Field(i).Interface()
fmt.Println("val :", val)
}
fmt.Println("=================方法====================")
for i := 0; i < t.NumMethod(); i++ {
m := t.Method(i)
fmt.Println(m.Name)
fmt.Println(m.Type)
} } func main() {
u := User{1, "zs", 20}
Poni(u)
}

查看匿名字段

package main

import (
"fmt"
"reflect"
) // 定义结构体
type User struct {
Id int
Name string
Age int
} // 匿名字段
type Boy struct {
User
Addr string
} func main() {
m := Boy{User{1, "zs", 20}, "bj"}
t := reflect.TypeOf(m)
fmt.Println(t)
// Anonymous:匿名
fmt.Printf("%#v\n", t.Field(0))
// 值信息
fmt.Printf("%#v\n", reflect.ValueOf(m).Field(0))
}

修改结构体的值

package main

import (
"fmt"
"reflect"
) // 定义结构体
type User struct {
Id int
Name string
Age int
} // 修改结构体值
func SetValue(o interface{}) {
v := reflect.ValueOf(o)
// 获取指针指向的元素
v = v.Elem()
// 取字段
f := v.FieldByName("Name")
if f.Kind() == reflect.String {
f.SetString("kuteng")
}
} func main() {
u := User{1, "5lmh.com", 20}
SetValue(&u)
fmt.Println(u)
}

调用方法

package main

import (
"fmt"
"reflect"
) // 定义结构体
type User struct {
Id int
Name string
Age int
} func (u User) Hello(name string) {
fmt.Println("Hello:", name)
} func main() {
u := User{1, "5lmh.com", 20}
v := reflect.ValueOf(u)
// 获取方法
m := v.MethodByName("Hello")
// 构建一些参数
args := []reflect.Value{reflect.ValueOf("6666")}
// 没参数的情况下:var args2 []reflect.Value
// 调用方法,需要传入方法的参数
m.Call(args)
}

获取字段的tag

package main

import (
"fmt"
"reflect"
) type Student struct {
Name string `json:"name1" db:"name2"`
} func main() {
var s Student
v := reflect.ValueOf(&s)
// 类型
t := v.Type()
// 获取字段
f := t.Elem().Field(0)
fmt.Println(f.Tag.Get("json"))
fmt.Println(f.Tag.Get("db"))
}

实例

方法

package common

import (
"errors"
"reflect"
"strconv"
"time"
) //根据结构体中sql标签映射数据到结构体中并且转换类型
func DataToStructByTagSql(data map[string]string, obj interface{}) {
objValue := reflect.ValueOf(obj).Elem()
for i := 0; i < objValue.NumField(); i++ {
//获取sql对应的值
value := data[objValue.Type().Field(i).Tag.Get("sql")]
//获取对应字段的名称
name := objValue.Type().Field(i).Name
//获取对应字段类型
structFieldType := objValue.Field(i).Type()
//获取变量类型,也可以直接写"string类型"
val := reflect.ValueOf(value)
var err error
if structFieldType != val.Type() {
//类型转换
val, err = TypeConversion(value, structFieldType.Name()) //类型转换
if err != nil { }
}
//设置类型值
objValue.FieldByName(name).Set(val)
}
} //类型转换
func TypeConversion(value string, ntype string) (reflect.Value, error) {
if ntype == "string" {
return reflect.ValueOf(value), nil
} else if ntype == "time.Time" {
t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
return reflect.ValueOf(t), err
} else if ntype == "Time" {
t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
return reflect.ValueOf(t), err
} else if ntype == "int" {
i, err := strconv.Atoi(value)
return reflect.ValueOf(i), err
} else if ntype == "int8" {
i, err := strconv.ParseInt(value, 10, 64)
return reflect.ValueOf(int8(i)), err
} else if ntype == "int32" {
i, err := strconv.ParseInt(value, 10, 64)
return reflect.ValueOf(int64(i)), err
} else if ntype == "int64" {
i, err := strconv.ParseInt(value, 10, 64)
return reflect.ValueOf(i), err
} else if ntype == "float32" {
i, err := strconv.ParseFloat(value, 64)
return reflect.ValueOf(float32(i)), err
} else if ntype == "float64" {
i, err := strconv.ParseFloat(value, 64)
return reflect.ValueOf(i), err
} //else if .......增加其他一些类型的转换 return reflect.ValueOf(value), errors.New("未知的类型:" + ntype)
}

调用

package main

import (
"fmt" "github.com/student/1129/common"
) //Product Product定义一个结构体
type Product struct {
ID int64 `json:"id" sql:"id"`
ProductClass string `json:"ProductClass" sql:"ProductClass"`
ProductName string `json:"ProductName" sql:"productName"`
ProductNum int64 `json:"ProductNum" sql:"productNum"`
ProductImage string `json:"ProductImage" sql:"productImage"`
ProductURL string `json:"ProductUrl" sql:"productUrl" `
} func main() {
//这块是模拟mysql获取单条的数据反射到结构体
data := map[string]string{"id": "1", "ProductClass": "blog", "productName": "5lmh.com", "productNum": "40", "productImage": "http://www.5lmh.com/", "productUrl": "http://www.5lmh.com/"}
productResult := &Product{}
common.DataToStructByTagSql(data, productResult)
fmt.Println(*productResult)
//这块是模拟mysql获取所有的数据反射到结构体
Alldata := []map[string]string{
{"id": "1", "ProductClass": "blog", "productName": "5lmh.com", "productNum": "40", "productImage": "http://www.5lmh.com/", "productUrl": "http://www.5lmh.com/"},
{"id": "2", "ProductClass": "blog", "productName": "5lmh.com", "productNum": "40", "productImage": "http://www.5lmh.com/", "productUrl": "http://www.5lmh.com/"},
}
var productArray []*Product
for _, v := range Alldata {
Allproduct := &Product{}
common.DataToStructByTagSql(v, Allproduct)
productArray = append(productArray, Allproduct)
}
for _, vv := range productArray {
fmt.Println(vv)
}
}

最新文章

  1. Java 多张图片合成一张 drawImage
  2. 将编码从GB2312转成UTF-8的方法汇总(从前台、程序、数据库)
  3. java-cef系列视频第二集:搭建开发环境
  4. 实验:传输层:UDP协议 学习笔记
  5. 找不到库文件地址,修改修改方法framework
  6. 自动计算尺寸列表功能案例ios源码
  7. Sublime Text 插件 autoprefixer
  8. android开发必备日志打印工具类
  9. matlab绘图方法汇总
  10. 日志快速筛选 之 linux命令grep|uniq|wc|awk
  11. iOS10访问用户权限的描述key值汇总
  12. Linux - 简单好用的计算器 bc
  13. Go基础系列:map类型
  14. python list用法
  15. dotnet 在build restore publish 的时候不显示警告
  16. wap2app(二)-- 设置APP系统状态栏
  17. IDEA 各版本在线激活(激活码)
  18. Silverlight中字典的使用
  19. Hyper-V 连网备忘
  20. Networx蓝屏问题

热门文章

  1. Ansible-Playbook中的变量使用
  2. vite 动态 import 引入打包报错解决方案
  3. 剑指offer二刷(精刷)
  4. 【笔记】《Redis设计与实现》chapter13 客户端
  5. 使用Vue-TreeSelect组件的时候,用watch变量方式解决弹出编辑对话框界面无法触发更新的问题
  6. Day16_92_Java IO 基础概念
  7. Day06_30_抽象类(Abstract)
  8. 基于excel的接口自动化测试框架:支持参数化、关联等
  9. php正则表达式过滤空格 换行符 回车
  10. DexExtractor的原理分析和使用说明