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. 在编译器修改源代码,在运行期字节码加载前 ...
随机推荐
- python接口自动化测试七:获取登录的Cookies
python接口自动化测试七:获取登录的Cookies,并关联到下一个请求 获取登录的cookies:loginCookies = r.cookies 把获取到的cookies传入请求:cooki ...
- 002:CSS基础
注意:蓝色 重要:红色 目录: 1. 学会使用CSS选择器: 9大选择器.交集选择器.并集选择器.后代选择器.子代选择器.伪类选择器. 2.font.color.横向竖向居中.文本修饰.首行缩进. f ...
- linux语句速查
一.netstat -a或--all:显示所有连线中的Socket -A<网络类型>或--<网络类型>:列出该网络类型连线中的相关地址 -c或--continuous:持续列出 ...
- 提交任务到spark(以wordcount为例)
1.首先需要搭建好hadoop+spark环境,并保证服务正常.本文以wordcount为例. 2.创建源文件,即输入源.hello.txt文件,内容如下: tom jerry henry jim s ...
- [C++] 空间配置器——allocator类
1.new和delete有一些灵活性上的局限:new把内存分配和对象构造组合在了一起:delete将对象析构和内存释放组合在了一起. 2.当分配一大块内存时,我们通常计划在这块内存上按需构造对象, ...
- Java中一维,二维数组的静态和动态初始化
今天我们要开始来讲讲Java中的数组,包括一维数组和二维数组的静态初始化和动态初始化 数组概述: 数组可以看成是多个相同类型数据的组合,对这些数据的统一管理; 数组变量属于引用数据类型,数组也可以看成 ...
- Linux 伪终端(pty)
通过<Linux 终端(TTY)>一文我们了解到:我们常说的终端分为终端 tty1-6 和伪终端.使用 tty1-6 的情况一般为 Linux 系统直接连了键盘和显示器,或者是使用了 vS ...
- python学习笔记之zipfile模块
为什么学习: 在做自动化测试平台的apk上传功能部分时候,涉及到apk上传后提取apk的icon图标,通过aapt解析apk,获取对应icon在apk中的地址,通过python的zipfile模块来解 ...
- Python2与Python3的map()
1. map()函数 Python2中,map(func, seq1[,seq2[...[,seqn)将func作用于seq*的每个序列的索引相同的元素,并最终生成一个[func(seq1[0], s ...
- Player的跟踪狂 -- Camera
P.S.很多游戏里的Player都会设置的被跟踪,是人性的扭曲,还是XXX,正在解密. 第三人称视角 camera紧跟player背后(角度随player改变) using System.Collec ...