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

成都网站建设哪家企业网站建设有几种

成都网站建设哪家,企业网站建设有几种,昆明手机网站建设,电子商务网站建设的需求本文参考了李文周的博客——Go语言基础之反射。 一、反射初识 1. 什么是反射 在计算机科学中#xff0c;反射是指计算机程序在运行时#xff08;run time#xff09;可以访问、检测和修改它本身状态和行为的一种能力。用比喻来说#xff0c;反射就是程序在运行的时候能够…本文参考了李文周的博客——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 (fmtreflect )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 (fmtreflect )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() boolIsNil()报告v持有的值是否为nilIsNil()常被用于判断指针是否为空。。v持有的值的分类必须是通道、函数、接口、映射、指针、切片之一否则IsNil函数会导致panic。 (2) isValid方法 func (v Value) IsValid() boolIsValid()返回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 (fmtreflect )// 定义一个结构体 type Person struct {Name string json:nameAge int json:ageSex 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 : zuzhiangparamList : 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://www.dnsts.com.cn/news/76369.html

相关文章:

  • 深圳营销网站建设服务网络营销策划书5000字
  • 官方网站建设调研报告艺术字体在线生成器华康海报
  • 建网站的流程及注意事项如何选择武进网站建设
  • 怎么做网站地图的样式青岛网站建设网站制作
  • 网站建设找云尚网络广州番禺楼盘
  • 建设个人网站第一步这么做潍坊网站开发招聘信息
  • 广州网站设计十年乐云seo推广策略
  • 做动态效果的插件网站湛江百度seo公司
  • 优化网站内容预付网站建设费会计处理
  • 网站后台管理密码忘记太原网站建设tygytc
  • 网站中的宣传册翻页动画怎么做简约风格网站建设
  • 绵阳网站维护托管wordpress回顶部
  • 网站ico怎么用最专业的做音乐网站
  • 张家港做网站优化价格查公司信息在哪里查
  • 亚马逊品牌网站要怎么做网站载入页面怎么做
  • 本人已履行网站备案信息wordpress不用邮件确认
  • 关于协会网站建设的几点思考html5网站后台制作
  • 网站备案号 如何添加注册个网站怎么注册
  • 网站建设乐云seo友情链接平台站长资源
  • 全国较好的网站建设公司网站seo软件
  • 网站织梦模板邢台网站制作平台
  • 做网站黑吃黑是什么罪互联网推广培训机构
  • php网站开发心得体会济南 微网站
  • 建设网站虚拟现实技术开发微信小程序多少钱
  • 住房和城乡建设局网站响应式网站 哪些
  • 合肥专业的房产网站建设船员专用网站开发建议
  • 温州住房与城乡建设部网站google 网站推广
  • 阿里云 拦截网站推广普通话的重要性
  • 模板网站什么意思微信投票网站制作
  • 朝阳网站制作设计那里做网站比较好