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. 在编译器修改源代码,在运行期字节码加载前 ...
随机推荐
- Springboot+Shiro+Mybatis+mysql
一 .shiro框架 Shiro是Apache 的一个强大且易用的Java安全框架,执行身份验证.授权.密码学和会话管理.Shiro 主要分为两个部分就是认证和授权两部分 1.Subject代表了当前 ...
- pip安装Mysql-python报错EnvironmentError: mysql_config not found
如下图,安装Mysql-python报错EnvironmentError: mysql_config not found 经过验证,可通过以下方式解决: 从官网下载mysql安装,成功之后输入PATH ...
- 2019年9月3日安卓凯立德全分辨率(路况)夏季版C3551-C7M24-3K21J25懒人包
拷贝懒人包NaviOne文件夹到机器根目录或内存卡根目录下:安装其中的apk程序 2019凯立德C3551-C7M24-3K21J25新组合懒人包 [分辨率]:自适应 [适用系统]:Android2. ...
- LeetCode 230.二叉树中第k小的元素
题目: 给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素. 说明:你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数. 这道题在leetCode上难 ...
- Loadrunner录制步骤及说明
做好业务准备,如环境配置.服务启动等 打开Virtual User Generator界面---->New---->选择协议,录制网页时一般选择Web(HTTP/HTML) Start R ...
- 基于Docker搭建大数据集群(六)Hive搭建
基于Docker搭建大数据集群(六)Hive搭建 前言 之前搭建的都是1.x版本,这次搭建的是hive3.1.2版本的..还是有一点细节不一样的 Hive现在解析引擎可以选择spark,我是用spar ...
- 使用mkfs.ext4格式化大容量磁盘
使用mkfs.ext4默认参数格式化磁盘后,发现格式化时间特别长,并且格式化会占用磁盘很大的空间.例如2TB的磁盘格式化会占用10分钟左右时间,并占用30G左右的磁盘空间.究其原因,原来inode会占 ...
- NN and the Optical Illusion-光学幻觉 CodeForce1100C 几何
题目链接:NN and the Optical Illusion 题目原文 NN is an experienced internet user and that means he spends a ...
- selenium-03-02操作元素-等待
1.最直接普通的方式:这个是设置固定的等待时间 Thread.sleep(1000); 2.隐式等待方式(implicitlyWait):设置脚本在查找元素时的最大等待时间: driv ...
- 远程桌面连接mstsc 超扎心
搞了一天问了几千个人.最后终于有一位大佬解决了.扎心啊. http://jingyan.baidu.com/article/39810a23edc48bb637fda672.html 就是服务没打开.