go反射----1类型
声明:文章内容取自雨痕老师《Go语言学习笔记》
反射( reflect )让我们能在运行期探知对象的类型信息和内存结构,这从一定程度上弥补了静态语言在动态行为上的不足。同时,反射还是元编程的重要手段。
和C数据结构一样,Go对象头部并没有类型指针,通过其自身是无法在运行期获知任何类型相关信息的。反射操作所需的全部信息都源自接口变量。接口变量除储存自身类型外,还会保存实际对象的类型数据。
func TypeOf(i interface{}) Type
func ValueOf(i interface{}) Value
这两个反射入口函数,会将任何传入的对象转换为接口类型。
在面对类型时,需要区分Type和Kind。前者表示真实类型( 静态类型 ),后者表示其基础结构( 底层类型 )类别。
package main
import (
"fmt"
"reflect"
)
type X int
func main() {
var a X = 100
t := reflect.TypeOf(a)
fmt.Println(t.Name(), t.Kind())
}
输出:
X int
所以在类型判断上,须选择正确的方式。
package main
import (
"fmt"
"reflect"
)
type X int
type Y int
func main() {
var a, b X = 100, 200
var c Y = 300
ta, tb, tc := reflect.TypeOf(a), reflect.TypeOf(b), reflect.TypeOf(c)
fmt.Println(ta == tb, ta == tc)
fmt.Println(ta.Kind() == tc.Kind())
}
输出:
true false
true
除通过实际对象获取类型外,也可以直接构造一些基础符合类型。
package main
import (
"fmt"
"reflect"
)
func main() {
a := reflect.ArrayOf(10, reflect.TypeOf(byte(0)))
m := reflect.MapOf(reflect.TypeOf(""), reflect.TypeOf(0))
fmt.Println(a, m)
}
输出:
[10]uint8 map[string]int
传入对象应区分基类型和指针类型,因为他们并不属于同一类型。
package main
import (
"fmt"
"reflect"
)
func main() {
x := 100
tx, tp := reflect.TypeOf(x), reflect.TypeOf(&x)
fmt.Println(tx, tp, tx == tp)
fmt.Println(tx.Kind(), tp.Kind())
fmt.Println(tx == tp.Elem())
}
输出:
int *int false
int ptr
true
方法Elem返回指针、数组、切片、字典(值)或通道的基类型。
package main
import (
"fmt"
"reflect"
)
func main() {
fmt.Println(reflect.TypeOf(map[string]int{}).Elem())
fmt.Println(reflect.TypeOf([]int32{}).Elem())
}
输出:
int
int32
只有在获取结构体指针的基类型后,才能遍历它的字段。
package main
import (
"fmt"
"reflect"
)
type user struct {
name string
age int
}
type manager struct {
user
title string
}
func main() {
var m manager
t := reflect.TypeOf(&m)
if t.Kind() == reflect.Ptr { //获取指针的基类型
t = t.Elem()
}
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
fmt.Println(f.Name, f.Type, f.Offset)
if f.Anonymous { //输出匿名字段结构
for x := 0; x < f.Type.NumField(); x++ {
af := f.Type.Field(x)
fmt.Println(" ", af.Name, af.Type)
}
}
}
}
输出:
user main.user 0
name string
age int
title string 24
对于匿名字段,可用多级索引(按定义顺序)直接访问。
package main
import (
"fmt"
"reflect"
)
type user struct {
name string
age int
}
type manager struct {
user
title string
}
func main() {
var m manager
t := reflect.TypeOf(m)
name, _ := t.FieldByName("name") //按名称查找
fmt.Println(name.Name, name.Type)
age := t.FieldByIndex([]int{0, 1}) //按多级索引查找
fmt.Println(age.Name, age.Type)
}
输出:
name string
age int
FieldByName 不支持多级名称,如有同名遮蔽,须通过匿名字段的二次获取
同样地,输出方法集时,一样区分基类型和指针类型。
```golang
package main
import (
"fmt"
"reflect"
)
type A int
type B struct {
A
}
func (a A) Av() {}
func (a *A) Ap() {}
func (b B) Bv() {}
func (b *B) Bp() {}
func main() {
var b B
t := reflect.TypeOf(&b)
s := []reflect.Type{t, t.Elem()}
for _, v := range s {
fmt.Println(v, "
go反射----1类型的更多相关文章
- c#反射机制学习和利用反射获取类型信息
反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的 ...
- Go语言反射之类型反射
1 概述 类似于 Java,Go 语言也支持反射.支持反射的语言可以在运行时对程序进行访问和修改.反射的原理是在程序编译期将反射信息(如类型信息.结构体信息等)整合到程序中,并给提供给程序访问反射信息 ...
- Protobuf的自动反射消息类型的方法
1. 每个消息头部中带上type name,作为消息的类型标识 2. 通过type name可以找到描述符Descriptor*, FindMessageTypeByName 3. 通过描述符Desc ...
- .Net反射-Type类型扩展
/// <summary> /// Type 拓展 /// </summary> public static class TypeExtensions { /// <su ...
- .Net 中的反射(查看基本类型信息) - Part.2
反射概述 和Type类 1.反射的作用 简单来说,反射提供这样几个能力:1.查看和遍历类型(及其成员)的基本信息和程序集元数据(metadata):2.迟绑定(Late-Binding)方法和属性.3 ...
- .Net配置文件——反射+配置文件存储类型实例
配置文件+反射确实去除了选择语句的繁琐,带来了优美的赶脚! 首先改进了一下类(接上文): ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ...
- .Net 中的反射(查看基本类型信息)
反射概述 和Type类 1.反射的作用 简单来说,反射提供这样几个能力:1.查看和遍历类型(及其成员)的基本信息和程序集元数据(metadata):2.迟绑定(Late-Binding)方法和属性.3 ...
- 【C#】.NET提供了哪些类型来实现反射
实现反射的类型大多数都定义在System.Reflection命名空间之下. Assembly 定义一个Assembly,它是可重用.无版本冲突并且可自我描述的公共语言运行库应用程序构造块. Asse ...
- python基础语法17 面向对象4 多态,抽象类,鸭子类型,绑定方法classmethod与staticmethod,isinstance与issubclass,反射
多态 1.什么是多态? 多态指的是同一种类型的事物,不同的形态. 2.多态的目的: “多态” 也称之为 “多态性”,目的是为了 在不知道对象具体类型的情况下,统一对象调用方法的规范(比如:名字). 多 ...
随机推荐
- scrapy-splash抓取动态数据例子十二
一.介绍 本例子用scrapy-splash通过搜狗搜索引擎,输入给定关键字抓取资讯信息. 给定关键字:数字:融合:电视 抓取信息内如下: 1.资讯标题 2.资讯链接 3.资讯时间 4.资讯来源 二. ...
- 【Hadoop】伪分布式环境搭建、验证
Hadoop伪分布式环境搭建: 自动部署脚本: #!/bin/bash set -eux export APP_PATH=/opt/applications export APP_NAME=Ares ...
- Android TextView 常见问题与使用总结
一.文字显示行数设置 1. 仅显示一行文字 android:singleLine="true" setTransformationMethod(TransformationMeth ...
- spark完全分布式集群搭建
最近学习Spark,因此想把相关内容记录下来,方便他人参考,也方便自己回忆吧 spark开发环境的介绍资料很多,大同小异,很多不能一次配置成功,我以自己的实际操作过程为准,详细记录下来. 1.基本运行 ...
- 我为什么学习Windows编程
前一段时间在看TCP/IP,在图书馆里面找了不少的书,其中有几本书还是不错的.比如: <Windows网络与通信程序设计(第二版)> 王艳平著 <WinSock网络编程经络> ...
- Spring Ajax一个简单样例
配置不说了.要在前面helloworld的样例基础上弄. 相同在hello下新建ajax.jsp <%@ page language="java" contentType=& ...
- 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-电机实际运行距离跟给定距离不一致怎么办,如何设置Scaling Factor
有时候,让电机从0度转到绝对的360度,有时候会出现电机实际转动更多或者更少的情况. 一般是电机的编码器的Scaling Factor Numerator数值不对导致的,数值越小,则同比转过角度越 ...
- 导入解析excel小结
导入解析excel小结 控制器例子:
- WPF入门教程系列四
WPF之Binding的使用(二) 一. 前言 初学WPF经常被Binding搞得苦不堪言,Binding的重用性就不做介绍了,在WPF应用程序开发中Binding是一个非常重要的部分.WPF也是近 ...
- tcp/ip--IP 协议首部格式与其配套使用的四个协议(ARP,RARP,ICMP,IGMP)
IP 数据报首部 最高位在左边,记为0 bit:最低位在右边,记为31 bit 版本: 占 4 位,指 IP 协议的版本目前的 IP 协议版本号为 4 (即 IPv4) 首部长度: 占4位,可表示的最 ...