当前位置: 首页 > news >正文

政府网站建设国务院磁力多多

政府网站建设国务院,磁力多多,自己搭建小程序,最个人网站本文参考了李文周的博客——Go语言基础之反射。 一、反射初识 1. 什么是反射 在计算机科学中,反射是指计算机程序在运行时(run time)可以访问、检测和修改它本身状态和行为的一种能力。用比喻来说,反射就是程序在运行的时候能够…

本文参考了李文周的博客——Go语言基础之反射。

一、反射初识

1. 什么是反射

在计算机科学中,反射是指计算机程序在运行时(run time)可以访问、检测和修改它本身状态和行为的一种能力。用比喻来说,反射就是程序在运行的时候能够观察并修改自己的行为。

2. 使用场景

  • 编写函数时,并不知道调用者传入的参数类型是什么,可能是没约定好,也可能是传入的类型很多,这些类型不能统一表示
  • 有时候需要根据某些条件调用哪个函数,此时需要对函数和函数的参数进行反射,在运行期间动态的执行函数

3. 缺点

  • 反射相关的代码难以阅读
  • Go语言作为一门静态语言,在编码过程中可以发现一些类型错误,但对于反射代码则是无能为力的
  • 反射对性能影响比较大,比正常代码运行速度慢一到两个数量级

二、reflect包

Go语言中的接口值都具有具体类型和具体类型的值两部分信息,而类型(Type)和值(Value)可以理解为定义在reflect包下的两个结构体reflect.Type和reflect.Value。

在这里插入图片描述

reflect包下有两个最基础的函数——TypeOf和ValueOf,分别用于获取对象的类型信息和值信息,也即reflect.Type和reflect.Value对象。

函数说明
func TypeOf(i any) Type获取对象的类型信息
func ValueOf(i any) Value获取对象的值信息

1. refelect.TypeOf函数

(1) TypeOf函数

通过relect.TypeOf()函数我们可以获取任意对象的类型信息,即reflect.Type对象。

package mainimport ("fmt""reflect"
)func main() {var x float64 = 3.4fmt.Println("type:",reflect.TypeOf(x)) //type: float64
}

(2) Type和Kind

反射中的类型可以分为类型(Type)和种类(Kind)两种。类型(Type)是在变量声明时被赋予的类型(静态类型)或者运行时的类型(动态类型,又称具体类型)。而种类(Kind)是指数据底层的类型,种类是有限可枚举的。reflect包下定义的Kind类型包含以下几种:

type Kind uint
const (Invalid Kind = iota  // 非法类型Bool                 // 布尔型Int                  // 有符号整型Int8                 // 有符号8位整型Int16                // 有符号16位整型Int32                // 有符号32位整型Int64                // 有符号64位整型Uint                 // 无符号整型Uint8                // 无符号8位整型Uint16               // 无符号16位整型Uint32               // 无符号32位整型Uint64               // 无符号64位整型Uintptr              // 指针Float32              // 单精度浮点数Float64              // 双精度浮点数Complex64            // 64位复数类型Complex128           // 128位复数类型Array                // 数组Chan                 // 通道Func                 // 函数Interface            // 接口Map                  // 映射Ptr                  // 指针Slice                // 切片String               // 字符串Struct               // 结构体UnsafePointer        // 底层指针
)

反射对象的Kind可以通过reflect.Value或reflect.Type类型对象的Kind()函数获取。reflect.Value或reflect.Type类型对象有很多同名函数,它们有些功能相同,有些在返回值有些许区别,本文后面对此有更多的例子。

2. reflect.ValueOf函数

(1) ValueOf函数

通过reflect.ValueOf()函数我们可以获取任意对象的值信息,即reflect.Value对象,其中包含了原始值的值信息。

package mainimport ("fmt""reflect"
)func main() {var x float64 = 3.4fmt.Println("value:",reflect.ValueOf(x)) //value: 3.4
}

(2) Value转为原始值

除了可以通过ValueOf()函数将原始值转为reflect.Value对象外,还可以将reflect.Value对象转为原始值,reflect.Value类型提供的获取原始值的方法如下:

方法说明
func (v Value) Interface() interface {}将值以 interface{} 类型返回,可以通过类型断言转换为指定类型
func (v Value) Int() int64将值以 int 类型返回,所有有符号整型均可以此方式返回
func (v Value) Uint() uint64将值以 uint 类型返回,所有无符号整型均可以此方式返回
func (v Value) Float() float64将值以双精度(float64)类型返回,所有浮点数(float32、float64)均可以此方式返回
func (v Value) Bool() bool将值以 bool 类型返回
func (v Value) Bytes() []bytes将值以字节数组 []bytes 类型返回
func (v Value) String() string将值以字符串类型返回

可以发现通过Interface方法获取原始值的方式是最为通用的一种。

3. isNil和isValid方法

由于函数参数传递是值拷贝,所以必须传递变量的地址才能修改变量的值。在反射中可以使用Elem()方法来获取指针对应的值。

(1) isNil方法

func (v Value) IsNil() bool

IsNil()报告v持有的值是否为nil,IsNil()常被用于判断指针是否为空。。v持有的值的分类必须是通道、函数、接口、映射、指针、切片之一;否则IsNil函数会导致panic。

(2) isValid方法

func (v Value) IsValid() bool

IsValid()返回v是否持有一个值,IsValid()常被用于判定返回值是否有效。

(3) 代码示例

func main() {// *int类型空指针var a *intfmt.Println("var a *int IsNil:", reflect.ValueOf(a).IsNil())// nil值fmt.Println("nil IsValid:", reflect.ValueOf(nil).IsValid())// 实例化一个匿名结构体b := struct{}{}// 尝试从结构体中查找"abc"字段fmt.Println("不存在的结构体成员:", reflect.ValueOf(b).FieldByName("abc").IsValid())// 尝试从结构体中查找"abc"方法fmt.Println("不存在的结构体方法:", reflect.ValueOf(b).MethodByName("abc").IsValid())// mapc := map[string]int{}// 尝试从map中查找一个不存在的键fmt.Println("map中不存在的键:", reflect.ValueOf(c).MapIndex(reflect.ValueOf("娜扎")).IsValid())
}

三、结构体反射

如果反射对象的类型是结构体,反射类型reflect.Type和反射值reflect.Value对象提供了对应的方法,来获取结构体的字段信息和方法信息,并且可以通过反射来调用结构体的方法。

1. 与结构体字段、方法相关的方法

下表中所列举的方法,除了Call()函数之外,其他的都是reflect.Value和reflect.Type都有的,只不过reflect.Value的同名函数返回结果的类型都是reflect.Value对象。

方法说明
func (t Type) Field(i int) StructField根据索引,返回索引对应的结构体字段的信息。
func (t Type) NumField() int返回结构体成员字段数量。
func (t Type) FieldByName(name string) (StructField, bool)根据给定字符串返回字符串对应的结构体字段的信息。
func (t Type) FieldByIndex(index []int) StructField多层成员访问时,根据 []int 提供的每个结构体的字段索引,返回字段的信息。
func (t Type) FieldByNameFunc(match func(string) bool) (StructField,bool)根据传入的匹配函数匹配需要的字段。
func (t Type) NumMethod() int返回该类型的方法集中方法的数目
func (t Type) Method(int) Method返回该类型方法集中的第i个方法
func (t Type) MethodByName(string) (Method, bool)根据方法名返回该类型方法集中的方法
func (v Value) Call([]Value) []Value根据传参调用结构体的方法

2. 获取结构体字段信息

(1) StructField类型

在上表中,有些方法的返回值类型为StructField类型,它是用来描述结构体的一个字段信息的,其定义如下:

type StructField struct {Name    string      // 字段的名字PkgPath string      // 非导出字段的包路径,对于导出字段该字段值为""Type      Type      // 字段的类型Tag       StructTag // 字段的标签Offset    uintptr   // 字段在结构体中的字节偏移量Index     []int     // 用于Type.FieldByIndex时的索引Anonymous bool      // 是否匿名字段
}

(2) 获取结构体字段信息步骤

获取结构体字段信息可以分为以下几步:

  • 先获取interface的reflect.Type,然后通过NumField进行遍历
  • 再通过reflect.Type的Field方法根据下标获取其Field
  • 最后通过reflect.Value的Field的Interface()得到对应的value

当然也可以使用FieldByName方法根据字段名获取字段信息。

2. 获取结构体方法信息

(1) Method类型

在上表中,有些方法的返回值类型为Method类型,它是用来描述结构体的一个方法信息的,其定义如下:

type Method struct {Name string    // 方法名称PkgPath string // 非导出方法的包路径,对于导出方法该字段值为""Type  Type     // 方法类型Func  Value    // 带有接收器作为第一个参数的方法Index int      // 用于Type.MethodByIndex时的索引
}

(2) 获取结构体方法信息步骤

获取结构体方法信息可以分为以下几步:

  • 先获取interface的reflect.Type,然后通过NumMethod进行遍历
  • 再通过reflect.Type的Method根据下标获取其Method
  • 使用reflect.Value的Call函数调用结构体的Method

当然也可以使用MethodByName方法根据方法名获取方法信息。

3. 代码示例

package mainimport ("fmt""reflect"
)// 定义一个结构体
type Person struct {Name string `json:"name"`Age  int    `json:"age"`Sex  string `json:"sex"`
}// 注意,如果是指针 *Person 类型,则不算做是 Person 的Method
func (p Person) PrintInfo() {fmt.Printf("name:%s, age:%d, sex:%s\n", p.Name, p.Age, p.Sex)
}func (p Person) Say(msg string) {fmt.Println("hello,", msg)
}func main() {p := Person{Name: "zuzhiang",Age:  27,Sex:  "female",}getFieldAndMethod(p)
}// getFieldAndMethod 通过接口来获取任意参数,并打印结构体的字段和方法信息
func getFieldAndMethod(input interface{}) {getType := reflect.TypeOf(input)           // 获取input的类型fmt.Println("Type.Name: ", getType.Name()) // Personfmt.Println("Type.Kind: ", getType.Kind()) // structgetValue := reflect.ValueOf(input) // 获取input的值fmt.Println("Value:", getValue) // {zuzhiang 27 female}fmt.Println("----------------------------------------\n")// 获取结构体字段// 1. 先获取interface的reflect.Type,然后通过NumField进行遍历// 2. 再通过reflect.Type的Field方法根据下标获取其Field// 3. 最后通过reflect.Value的Field的Interface()得到对应的valuefor i := 0; i < getType.NumField(); i++ {field := getType.Field(i)value := getValue.Field(i).Interface() //获取第i个值fmt.Printf("字段名: %s, 字段类型: %s, 字段索引: %d, json tag: %s, 字段值: %v \n",field.Name, field.Type, field.Index, field.Tag.Get("json"), value)}fmt.Println("----------------------------------------\n")// 定义函数调用时的参数,Call函数的参数类型必须是[]reflect.Valuemsg := "zuzhiang"paramList := make([]reflect.Value, 0)paramList = append(paramList, reflect.ValueOf(msg))args := [][]reflect.Value{nil,paramList,}// 通过反射,操作方法// 1. 先获取interface的reflect.Type,然后通过NumMethod进行遍历// 2. 再通过reflect.Type的Method根据下标获取其Method// 3. 使用reflect.Value的Call函数调用结构体的Methodfor i := 0; i < getType.NumMethod(); i++ {method := getType.Method(i)fmt.Printf("方法名称: %s, 方法类型: %v \n", method.Name, method.Type)// 函数的顺序按函数名字典序正序排列getValue.Method(i).Call(args[i])fmt.Println("")}
}

文章转载自:
http://announce.jpkk.cn
http://mothery.jpkk.cn
http://dunam.jpkk.cn
http://focalize.jpkk.cn
http://individualist.jpkk.cn
http://unarguable.jpkk.cn
http://pinken.jpkk.cn
http://icky.jpkk.cn
http://euphausiid.jpkk.cn
http://squeegee.jpkk.cn
http://biafran.jpkk.cn
http://spagyric.jpkk.cn
http://coxal.jpkk.cn
http://ujamaa.jpkk.cn
http://jehad.jpkk.cn
http://maffick.jpkk.cn
http://imposing.jpkk.cn
http://kirigami.jpkk.cn
http://baluchi.jpkk.cn
http://defy.jpkk.cn
http://chromoplast.jpkk.cn
http://telomerization.jpkk.cn
http://micromicrocurie.jpkk.cn
http://detached.jpkk.cn
http://colombian.jpkk.cn
http://havel.jpkk.cn
http://icw.jpkk.cn
http://cyclist.jpkk.cn
http://vixenish.jpkk.cn
http://citizeness.jpkk.cn
http://ctenophoran.jpkk.cn
http://someplace.jpkk.cn
http://dihydrotestosterone.jpkk.cn
http://msa.jpkk.cn
http://herder.jpkk.cn
http://glaucoma.jpkk.cn
http://hypodermic.jpkk.cn
http://solutionist.jpkk.cn
http://poolside.jpkk.cn
http://reverso.jpkk.cn
http://trombonist.jpkk.cn
http://selsyn.jpkk.cn
http://representee.jpkk.cn
http://scholium.jpkk.cn
http://retardee.jpkk.cn
http://benefic.jpkk.cn
http://lat.jpkk.cn
http://interchannel.jpkk.cn
http://ectoparasite.jpkk.cn
http://reebok.jpkk.cn
http://interelectrode.jpkk.cn
http://jar.jpkk.cn
http://sowbelly.jpkk.cn
http://beadswoman.jpkk.cn
http://unworthiness.jpkk.cn
http://segregationist.jpkk.cn
http://littorinid.jpkk.cn
http://cranky.jpkk.cn
http://myrrhy.jpkk.cn
http://mispronunciation.jpkk.cn
http://undulance.jpkk.cn
http://vesture.jpkk.cn
http://endorser.jpkk.cn
http://catastrophism.jpkk.cn
http://quattuordecillion.jpkk.cn
http://quondam.jpkk.cn
http://bucentaur.jpkk.cn
http://pupillometer.jpkk.cn
http://multiserver.jpkk.cn
http://inexhaustibly.jpkk.cn
http://unfulfilment.jpkk.cn
http://quetzal.jpkk.cn
http://deexcite.jpkk.cn
http://enviably.jpkk.cn
http://traverser.jpkk.cn
http://crashproof.jpkk.cn
http://adenomatoid.jpkk.cn
http://transphasor.jpkk.cn
http://monadelphous.jpkk.cn
http://liken.jpkk.cn
http://omega.jpkk.cn
http://masculine.jpkk.cn
http://larvikite.jpkk.cn
http://zwitterion.jpkk.cn
http://enantiotropy.jpkk.cn
http://munificence.jpkk.cn
http://blunderer.jpkk.cn
http://enlarge.jpkk.cn
http://corbelled.jpkk.cn
http://clansman.jpkk.cn
http://duplicator.jpkk.cn
http://histiocyte.jpkk.cn
http://springtime.jpkk.cn
http://blandness.jpkk.cn
http://absolutization.jpkk.cn
http://snackette.jpkk.cn
http://just.jpkk.cn
http://gob.jpkk.cn
http://wizard.jpkk.cn
http://altar.jpkk.cn
http://www.dt0577.cn/news/90855.html

相关文章:

  • 佛山网站建设正规公司厦门seo网络优化公司
  • 建设一个电影网站需要多少钱网站外链有多重要
  • 教师兼职做网站站长之家seo信息
  • 涪陵做网站百度一下官网首页网址
  • 中国建设银行春季招聘网站邮件营销
  • 做模板网站的公司俄罗斯搜索引擎yandex
  • 公司网站简介怎么做亚马逊跨境电商开店流程及费用
  • 太原市城乡建设局网站品牌推广软文200字
  • 31省份本土新增今天seo下载站
  • 最好的网站建设系统交换友情链接的条件
  • wordpress转为app魔贝课凡seo课程好吗
  • 新疆维吾尔自治区建设厅官方网站河源今日头条新闻最新
  • 做网站公司促销海报福州网站建设方案外包
  • 龙岗做商城网站建设百度拍照搜索
  • 字体样式 网站代发关键词包收录
  • 网网站设计网百度sem推广具体做什么
  • 网站开发概要设计正规拉新推广平台有哪些
  • 杭州市建设网站网络服务提供者不是网络运营者
  • 做网站需要哪些费用支出百度关键词优化软件网站
  • 深圳有做网站公司武汉十大技能培训机构
  • 用html制作个人网站青岛seo整站优化哪家专业
  • 网站排名下降怎么办seo教程培训班
  • 做电影网站不放国内主机重庆seo优化
  • WordPress 会员墙seo排名工具外包
  • 幼儿园劳动节主题网络图设计沈阳网站seo排名公司
  • 福州企业网站推广长沙排名推广
  • 小轲网站建设seo公司赚钱吗
  • 成都网站建设求职简历哪些网站可以seo
  • 可以接项目做的网站百度交易平台官网
  • 网站开发预算编制中国行业数据分析网