GO反射类实例
变量的内在机制
类型信息:是静态的元信息,是预先定义好的
值信息:是程序运行过程中动态改变的
反射的使用
获取类型信息: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)
}
}
GO反射类实例的更多相关文章
- 自己动手之使用反射和泛型,动态读取XML创建类实例并赋值
前言: 最近小匹夫参与的游戏项目到了需要读取数据的阶段了,那么觉得自己业余时间也该实践下数据相关的内容.那么从哪入手呢?因为用的是Unity3d的游戏引擎,思来想去就选择了C#读取XML文件这个小功能 ...
- PHP的反射类ReflectionClass、ReflectionMethod使用实例
PHP5 具有完整的反射API,添加对类.接口.函数.方法和扩展进行反向工程的能力. 反射是什么? 它是指在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类.方法.属性.参数等的详细信息,包括 ...
- C# 反射 通过类名创建类实例
“反射”其实就是利用程序集的元数据信息. 反射可以有很多方法,编写程序时请先导入 System.Reflection 命名空间. 1.假设你要反射一个 DLL 中的类,并且没有引用它(即未知的类型): ...
- C#反射实例应用--------获取程序集信息和通过类名创建类实例
AppDomain.CurrentDomain.GetAssemblies();获取程序集,但是获取的只是已经加载的dll,引用的获取不到. System.Reflection.Assembly.Ge ...
- C#反射 获取程序集信息和通过类名创建类实例(转载)
C#反射获取程序集信息和通过类名创建类实例 . System.Reflection 命名空间:包含通过检查托管代码中程序集.模块.成员.参数和其他实体的元数据来检索其相关信息的类型. Assembly ...
- 利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理
利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理 2018-3-10 15:18 | 发布:Admin | 分类:代码库 | 评论: ...
- [No000085]C#反射Demo,通过类名(String)创建类实例,通过方法名(String)调用方法
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Sy ...
- C#语法糖之 ReflectionSugar 通用反射类
用法很简单: ReflectionSugar rs = new ReflectionSugar(100);//缓存100秒 ,可以不填默认不缓存 rs.有嘛点嘛 性能测试: 性能测试类源码: ht ...
- (转载)php反射类 ReflectionClass
(转载)http://hi.baidu.com/daihui98/item/a67dfb8213055dd75f0ec165 php反射类 ReflectionClass 什么是php反射类,可以 ...
随机推荐
- 【安全研究】Domain fronting域名前置网络攻击技术
出品|MS08067实验室(www.ms08067.com) 千里百科 Domain Fronting基于HTTPS通用规避技术,也被称为域前端网络攻击技术.这是一种用来隐藏Metasploit,Co ...
- Python数据分析入门(六):Pandas的函数应用
apply和applymap 1. 可直接使用NumPy的函数 示例代码: # Numpy ufunc 函数 df = pd.DataFrame(np.random.randn(5,4) - 1) p ...
- [树形DP]没有上司的晚会
没 有 上 司 的 晚 会 没有上司的晚会 没有上司的晚会 题目描述 Ural大学有N个职员,编号为1~N.他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.每个职 ...
- 使用 shell 做 tcp 协议模拟
问题背景 公司有一套消息推送系统(简称GCM),由于人事变动接手了其中的客户端部分.看了一下文档,仅通讯协议部分有几页简单的说明,代码呢又多又乱,一时理不出一个头绪.由于消息是从后台推送到端的,所以使 ...
- 敏捷史话(十四):敏捷之峰的攀登者 —— Jim Highsmith
"我们希望,一起组成的敏捷联盟能够帮助到其他同行,帮他们用新的更'敏捷'的方式去思考软件开发.方法论和组织.做到这一点,我们就得偿所愿了."Jim Highsmith 在雪鸟会议结 ...
- 消息中间件-RabbitMQ消息可靠性和插件化机制
package com.study.rabbitmq.a132.confirm; import com.rabbitmq.client.*; import java.io.IOException; i ...
- xctf - forgot
xctf - forgot check一下,开启了NX 拉入ida中,能找到: __isoc99_scanf,能够无限输入, 循环中,读取32个scanf的字符并进行判断,最后根据结果调用存在栈上的函 ...
- aws EKS EFS storageclass PV PVC Pod
storageclass [root@localhost specs]# cat storageclass.yaml kind: StorageClass apiVersion: storage.k8 ...
- 详解Linux指令与文件的搜寻
我们在管理Linux服务器时通常会进行搜索文件及目录操作,下面我们就开始了解一下linux目录结构的相关知识. 博主再奉上一套零基础入门Linux视频,带你从入门到精通 https://www.bil ...
- kubespray续签k8s证书
查看证书过期时期 [root@node1 ~]# openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text |grep ' Not ...