go-接口-反射
接口类型总是代表着某一种类型(即所有实现它的类型)的行为。
一个接口类型的声明通常会包含关键字type、类型名称、关键字interface以及由花括号包裹的若干方法声明。
type Animal interface {
Grow()
Move(string) string
}
接口类型中的方法声明是普通的方法声明的简化形式。
它们只包括方法名称、参数声明列表和结果声明列表。
其中的参数的名称和结果的名称都可以被省略。
不过,出于文档化的目的,建议写上它们。
因此,Move方法的声明至少应该是这样的:
Move(new string) (old string)
一个数据类型所拥有的方法集合中包含了某一个接口类型中的所有方法声明的实现,那么就可以说这个数据类型实现了那个接口类型。
不能在一个非接口类型的值上应用类型断言来判定它是否属于某一个接口类型的。
我们必须先把前者转换成空接口类型的值。
Go语言的类型转换规则定义了是否能够把一个类型的值转换另一个类型的值。
空接口类型即是不包含任何方法声明的接口类型,用interface{}表示,常简称为空接口。
正因为空接口的定义,Go语言中的包含预定义的任何数据类型都可以被看做是空接口的实现。
我们可以直接使用类型转换表达式把一个*Person类型转换成空接口类型的值.
p := Person{"Robert", "Male", , "Beijing"}
v := interface{}(&p)
然后就可以在v上应用类型断言了,即:
h, ok := v.(Animal)
类型断言表达式v.(Animal)的求值结果可以有两个。
第一个结果是被转换后的那个目标类型(这里是Animal)的值,
而第二个结果则是转换操作成功与否的标志。
显然,ok代表了一个bool类型的值。
它也是这里判定实现关系的重要依据。
package main import (
"fmt"
) type humaner interface {
sayHello() //接口只有声明没有实现。
} type Studnt struct {
name string
age int
} func (tmp *Studnt) sayHello() {
fmt.Println("i am student")
} type Teacher struct {
name string
age int
} func (tmp *Teacher) sayHello() {
fmt.Println("i am Teacher")
} func whoSayHi(i humaner) {
i.sayHello()
} func main() {
//定义接口类型变量
var h humaner
//实现了此接口的方法类型,那么这个类型的变量就可以给i赋值。
s := &Studnt{"break", }
h = s
h.sayHello() t := &Teacher{"Tony", }
//通过接口调用实现多态
whoSayHi(s)
whoSayHi(t) //创建一个切片
x := make([]humaner, )
x[] = s
x[] = t
for _, hum := range x {
hum.sayHello()
}
}
package main import (
"fmt"
) type humaner interface { //子集
sayHello() //接口只有声明没有实现。
} type persion interface { //超集
humaner //匿名字段继承sayHello
sing(lrc string)
} type Studnt struct {
name string
age int
} //实现了sayHello
func (tmp *Studnt) sayHello() {
fmt.Println("i am student")
} //实现了sing
func (tmp *Studnt) sing(lrc string) {
fmt.Println(lrc)
} func main() {
//定义一个接口类型变量
var per persion
s := &Studnt{"break", }
per = s per.sayHello() //继承过来的接口
per.sing("la la la") //超集可以转化为子集,反过来不行
var h humaner
h = per
h.sayHello() //空接口 实际上就是一个万能类型, 可以保存任意类型值
var i interface{} =
fmt.Println(i)
i = "abc"
fmt.Println(i) //类型断言
if value, ok := i.(string); ok == true {
fmt.Println(value)
} i = Studnt{"break", }
if value, ok := i.(Studnt); ok == true {
fmt.Println(value.name)
} switch i.(type) {
case Studnt:
fmt.Println("Studnt")
case int:
fmt.Println("int")
} }
反射例子
type Student struct {
Name string
Age int
Score float32
} func test(b interface{}) {
t := reflect.TypeOf(b)
fmt.Println(t) v := reflect.ValueOf(b)
k := v.Kind()
fmt.Println(k) iv := v.Interface()
stu, ok := iv.(Student)
if ok {
fmt.Printf("%v %T\n", stu, stu)
}
} func TestStruct(a interface{}) {
tye := reflect.TypeOf(a)
val := reflect.ValueOf(a)
kd := val.Kind()
if kd != reflect.Ptr && val.Elem().Kind() == reflect.Struct {
fmt.Println("expect struct")
return
} num := val.Elem().NumField()
val.Elem().Field().SetString("stu1000")
for i := ; i < num; i++ {
fmt.Printf("**%d %v\n", i, val.Elem().Field(i).Kind())
} fmt.Printf("struct has %d fields\n", num) tag := tye.Elem().Field().Tag.Get("json")
fmt.Printf("tag=%s\n", tag) numOfMethod := val.Elem().NumMethod()
fmt.Printf("struct has %d methods\n", numOfMethod)
var params []reflect.Value
val.Elem().Method().Call(params)
} test(a)
TestStruct(a)
go-接口-反射的更多相关文章
- golang(6): 接口 & 反射
接口详解 // 举例:sort包中的 Sort 函数,如下: func Sort(data Interface) Sort sorts data. It makes one call to data. ...
- .NET接口和类 反射的差异性发现
1 背景 在项目中使用反射,反射出某类型的所有属性(Property)和对应的属性值.起初为了性能考虑在模块首次加载就反射类型的所有属性并将其存入字典.根据一般的编程规范——基于接口编程,所以首次传入 ...
- Spring反射机制
Spring是分层的Java SE/EE应用一站式的轻量级开源框架,以IoC(Inverse of Control)和AOP(Aspect Oriented Programming)为内核,提供了展现 ...
- 【反射】——Autofac 类型注册
Autofac是.net界一款轻量化的IOC组件,使用Autofac可以帮助完成代码中很多依赖注入工作.在以前文章中,介绍过Autofac的配置过程(http://www.cnblogs.com/Jn ...
- C# 反射机制以及方法
目录: 一. 反射的主要特性 1.反射中一个非常重要的类型就是 Type 1)当没有对象的时候使用这种方式来获取某个类型的Type 2)当已经获得对象后通过对象的GetType()方法来获取指定对象的 ...
- Java高级-反射
1.如何创建Class的实例 1.1过程:源文件经过编译(javac.exe)以后,得到一个或者多个.class文件..class文件经过运行(java.exe)这步,就需要进行类的加载(通过JVM的 ...
- AOP的实现原理
1 AOP各种的实现 AOP就是面向切面编程,我们可以从几个层面来实现AOP. 在编译器修改源代码,在运行期字节码加载前修改字节码或字节码加载后动态创建代理类的字节码,以下是各种实现机制的比较. 类别 ...
- c# c++ oc java || mac android ios
Unity 使用C/C++ 跨平台终极解决方案(PC,iOS,Android,以及支持C/C++的平台) http://blog.csdn.net/fg5823820/article/details/ ...
- java中动态代理实现机制
前言: 代理模式是常用的java设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系 ...
- AOP的实现机制--转
原文地址:http://www.iteye.com/topic/1116696 1 AOP各种的实现 AOP就是面向切面编程,我们可以从几个层面来实现AOP. 在编译器修改源代码,在运行期字节码加载前 ...
随机推荐
- ACM团队周赛题解(1)
这次周赛题目拉了CF315和CF349两套题. 因为我代码模板较长,便只放出关键代码部分 #define ll long long #define MMT(s,a) memset(s, a, size ...
- Metasploit工具----辅助模块
Metasploit框架(Metasploit Framework,MSF)是一个开源工具,旨在方便渗透测试,他是有Ruby程序语言编写的模板化框架,具有很好的扩展性,便于渗透测试人员开发.使用定制的 ...
- 一个基于vue的时钟
前两天写了一个基于vue的小钟表,给大家分享一下. 其中时针和分针使用的是图片,结合transform制作:表盘刻度是通过transform和transformOrigin配合画的:外面的弧形框框,啊 ...
- springboot项目启动报错 url' attribute is not specified and no embedded datasource could be configured
报错相关信息: 2019-07-22 17:12:48.971 ERROR 8312 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : **** ...
- 基于vue实现搜索高亮关键字
有一个需求是在已有列表中搜索关键词,然后在列表中展示含有相关关键字的数据项并且对关键字进行高亮显示,所以该需求需要解决的就两个问题: 1.搜索关键词过滤列表数据 2.每个列表高亮关键字 ps: 此问题 ...
- FPGA、GPU、CPU三者各自的优缺点是什么呢?
CPU: 英文全称:Central Processing Unit. 中文全称:中央处理器. 厂商:英特尔Intel. 功能:是一台计算机的运算核心和控制核心. 缺点:运算能力(最弱),核处理数(最少 ...
- 理解JavaScript中的this关键字
JavaScript中this关键字理解 在爬虫的过程中遇到了前端的js代码,对于this关键字理解的不是很清楚,所以写下这篇笔记,不足之处,希望得以改之. this的指向在函数定义的时候无法确定,只 ...
- react redux 二次开发流程
在一个大项目中如何引入redux及其相关技术栈(react-redux redux-thunk redux-immutable ),已经成为react前端工程师不可或缺的技能,下面通过实现一个简单的t ...
- Python数据结构 - 利用headp模块寻找最大N个元素并实现优先队列
用headp找到最大最小的N个值 import heapq nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2] print(heapq.nlargest(3, ...
- Kubernetes 系列(三):Kubernetes使用Traefik Ingress暴露服务
一.Kubernetes 服务暴露介绍 从 kubernetes 1.2 版本开始,kubernetes提供了 Ingress 对象来实现对外暴露服务:到目前为止 kubernetes 总共有三种暴露 ...