热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[golang]golangreflect详细用法整理

本博客原创博文版权所有@Allyvipally@gmail.com仅供交流学习使用用于商业用途请联系原作者转载请注
本博客原创博文版权所有 @Allyvipally@gmail.com
仅供交流学习使用用于商业用途请联系原作者 
转载请注明出处:http://blog.sina.com.cn/ally2014
 
最近在尝试用Go写一些东西,发现Go不支持泛型确实是一件比较蛋疼的事,同样功能的一个类,只有底层数据结构有一点点差异,需要实现N遍。特别像我这种在C++世界挣扎也纠结了很多年,用惯了模板编程思想的程序猿。好在Golang提供了reflect机制,可以在一定程度上满足对泛型编程的一些需求。
想实现的一些需求:
1.通过类型字符串动态创建类型对象
2.动态的调用一些预定义函数,而不需要依赖实现该函数的package
3.实现一些通用的数据结构,比如像C++ STL那样的泛型容器
4.一些特定类型的检查和操作 如chan Type,[]Type
5...
 
//---------------------------------以下是用reflect实现一些类型无关的泛型编程示例
//new object same the type as sample
func New(sample interface{}) interface{} {
    t :=reflect.ValueOf(sample).Type()
    v :=reflect.New(t).Interface()
    returnv
}
//---------------------------------check type of aninterface
func CheckType(val interface{}, kind reflect.Kind) bool {
    v :=reflect.ValueOf(val)
    return kind== v.Kind()
}
//---------------------------------if _func is not a functionor para num and type not match,it will cause panic
func Call(_func interface{}, params ...interface{}) (result[]interface{}, err error) {
    f :=reflect.ValueOf(_func)
    iflen(params) != f.Type().NumIn() {
       ss := fmt.Sprintf("The number of params is not adapted.%s",f.String())
       panic(ss)
       return
    }
    var in[]reflect.Value
    iflen(params) > 0 { //prepare in paras
       in = make([]reflect.Value, len(params))
       for k, param := range params {
           in[k] = reflect.ValueOf(param)
       }
    }
    out :=f.Call(in)
    if len(out)> 0 { //prepare out paras
       result = make([]interface{}, len(out), len(out))
       for i, v := range out {
           result[i] = v.Interface()
       }
    }
    return
}
//---------------------------------if ch is not channel,itwill panic
func ChanRecv(ch interface{}) (r interface{}) {
    v :=reflect.ValueOf(ch)
    if x, ok :=v.Recv(); ok {
       r = x.Interface()
    }
    return
}
//---------------------------------reflect fields of astruct
func reflect_struct_info(it interface{}) {
    t :=reflect.TypeOf(it)
   fmt.Printf("interface info:%s %s %s %s\n", t.Kind(), t.PkgPath(),t.Name(), t)
    if t.Kind()== reflect.Ptr { //if it is pointer, get it element type
       tt := t.Elem()
       if t.Kind() == reflect.Interface {
           fmt.Println(t.PkgPath(), t.Name())
           for i := 0; i                f := tt.Method(i)
               fmt.Println(i, f)
           }
       }
    }
    v :=reflect.ValueOf(it)
    k :=t.Kind()
    if k ==reflect.Ptr {
       v = v.Elem() //指针转换为对应的结构
       t = v.Type()
       k = t.Kind()
    }
   fmt.Printf("value type info:%s %s %s\n", t.Kind(), t.PkgPath(),t.Name())
    if k ==reflect.Struct { //反射结构体成员信息
       for i := 0; i            f := t.Field(i)
           fmt.Printf("%s %v\n", i, f)
       }
       for i := 0; i            f := t.Method(i)
           fmt.Println(i, f)
       }
       fmt.Printf("Fileds:\n")
       f := v.MethodByName("func_name")
       if f.IsValid() { //执行某个成员函数
           arg := []reflect.Value{reflect.ValueOf(int(2))}
           f.Call(arg)
   

推荐阅读
  • 本文整理了315道Python基础题目及答案,帮助读者检验学习成果。文章介绍了学习Python的途径、Python与其他编程语言的对比、解释型和编译型编程语言的简述、Python解释器的种类和特点、位和字节的关系、以及至少5个PEP8规范。对于想要检验自己学习成果的读者,这些题目将是一个不错的选择。请注意,答案在视频中,本文不提供答案。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • EzPP 0.2发布,新增YAML布局渲染功能
    EzPP发布了0.2.1版本,新增了YAML布局渲染功能,可以将YAML文件渲染为图片,并且可以复用YAML作为模版,通过传递不同参数生成不同的图片。这个功能可以用于绘制Logo、封面或其他图片,让用户不需要安装或卸载Photoshop。文章还提供了一个入门例子,介绍了使用ezpp的基本渲染方法,以及如何使用canvas、text类元素、自定义字体等。 ... [详细]
  • 使用圣杯布局模式实现网站首页的内容布局
    本文介绍了使用圣杯布局模式实现网站首页的内容布局的方法,包括HTML部分代码和实例。同时还提供了公司新闻、最新产品、关于我们、联系我们等页面的布局示例。商品展示区包括了车里子和农家生态土鸡蛋等产品的价格信息。 ... [详细]
  • EPPlus绘制刻度线的方法及示例代码
    本文介绍了使用EPPlus绘制刻度线的方法,并提供了示例代码。通过ExcelPackage类和List对象,可以实现在Excel中绘制刻度线的功能。具体的方法和示例代码在文章中进行了详细的介绍和演示。 ... [详细]
author-avatar
小茜的阳光2011_950
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有