七、golang中接口、反射
一、接口定义
1、定义
interface类型可以定义一组方法,但是这些不需要实现,并且interface不能包含任何变量
package main import (
"fmt"
) type test interface{
print()
} type Student struct{
name string
age int
score int
} func (p *Student)print(){
fmt.Println("name",p.name)
fmt.Println("age",p.age)
fmt.Println("score",p.score)
} func main(){
var t test //创建接口对象
var stu Student=Student{ //实例化结构体
name:"stu1",
age:20,
score:100,
}
t=&stu //把实例化传给这个接口对象
t.print() //接口对象来调用接口的方法
}
name stu1
age 20
score 100
上面的test就是一种类型
多态:
一种食物的多种形态,都可以按照统一的接口进行操作
上面的t可以指向Stu,也可以指向其他类型,这个就是多态
定义:
比如:
type example interface{
method1(参数列表) 返回值列表
method2(参数列表) 返回值列表
}
interface类型默认是一个指针
接口实现:
a、golang中的接口,不需要显示的实现,只要一个变量,含有接口类型中的所有方法,那么这个变量就实现这个接口
b、如果一个变量含有多个interface类型的方法,那么这个变量就实现了多个接口
c、要实现变量中接口的所有方法,才是实现了这个接口
接口嵌套:
一个接口可以嵌套在另外的接口,如下所示
type ReadWrite interface{
Read(b Buffer) bool
Write(b Buffer)bool
}
type Lock interface{
Lock()
Unlock()
}
type File interface{
ReadWrite
Lock
Close()
}
类型断言
类型断言,由于接口是一般类型,不知道具体类型,如果要转成具体类型,可以采用以下方法进行转换
var t int var t int
var x interface{} var x interface {}
x=t x=t
y=x.(int)//转成int y ,ok=x.(int) //转成int,带检查
二叉排序树

时间复杂度和二分查找时间复杂度是一样的
为什么要使用接口?
接口是一个规范,不需要关注类等的实现。即,数据本来在mysql里面然后突然变成pg里面,只要接口不变,使用方就不需要更改
如果接口里面没有任何方法,那么我们就叫这个接口为空接口
package main import (
"fmt"
) type Carer interface{
GetName() string
Run()
DIDI()
} func main(){
var car Carer
fmt.Println(car) //<nil>
}
上面打印出这个接口的值为nil
下面具体接口的用法:
package main
import (
"fmt"
)
type Carer interface{
GetName() string //这里前面定义的方法,后面代表返回值类型
Run()
DIDI()
}
type BWM struct{
Name string
}
func (p *BWM)GetName() string{
return p.Name
}
func (p *BWM)Run(){
fmt.Printf("%s is
Running",p.Name)
}
func (p *BWM)DIDI(){
fmt.Printf("%s is
didi",p.Name)
}
func main(){
var car Carer
fmt.Println(car) //<nil>
bwm:=BWM{
Name:"bwm",
}
car=&bwm
car.Run()
}
接口操作小结:
1、定义接口和方法,注意返回值
2、定义类型
3、定义类型实现的接口的方法,注意这里要实现接口所有的方法
4、声明定义的类型,声明接口变量的类型并且初始化,并把定义的类型赋值给接口变量的类型,注意指针
5、用定义的接口变量执行接口方法
鸭子类型
只要实现了接口相关的协议,那么这个就是接口
如sort只需要实现下面的接口就可以
func Sort(data Interface) 这里只需要传入接口就可以了
这个接口实现下面的方法
type Interface interface{
Len()
int 长度
Less(I,j
int) bool 比较两个数
Swap(I,j
int) 交换两个数
}
注意下面的大小写
package main import (
"fmt"
"math/rand" "sort"
) type Student struct{
Name string
Id string
Age int
} type StudentArray []Student //定义这个是切片结构体 func (p StudentArray) Len() int {
return len(p)
} func (p StudentArray)Less(i,j int)bool{
return p[i].Name>p[j].Name //从大到小
} func (p StudentArray)Swap(i,j int){
p[i],p[j]=p[j],p[i]
} func main() {
var stus StudentArray
for i := 0; i < 10; i++ {
stu := Student{
Name: fmt.Sprintf("stu%d", rand.Intn(100)),
Id: fmt.Sprintf("110%d", rand.Int()),
Age: rand.Intn(100),
} stus = append(stus, stu)
} for _, v := range stus {
fmt.Println(v)
}
//空行
fmt.Println("\n\n")
//由于这里实现了sort的接口,所以这里可以直接调用
sort.Sort(stus)
for _, v := range stus {
fmt.Println(v)
}
}
反射
反射,可以在运行时动态获取变量的相关信息
import (“reflect”)
两个函数
a)reflect.TypeOf,获取变量的类型,返回reflect.Type类型
b)reflect.ValueOf 获取变来那个的值,返回reflect.Value类型
c) reflect.Value.Kind 获取变量的类别,返回一个变量
d) reflect.value.Interface() 转换成interface类型
a和c的区别:
类型和类别的区别
类别范围》类型

package main import(
"fmt"
"reflect"
) type Student struct{
Name string
Age int
Score float32
} func test(b interface {}){
t:=reflect.TypeOf(b)
fmt.Println(t) //main.Student 类型 v:=reflect.ValueOf(b)
k:=v.Kind()
fmt.Println(k) //struct类别 iv:=v.Interface()
stu,ok:=iv.(Student)
if ok{
fmt.Printf("%v %T\n",stu,stu)//{stu01 18 92} main.Student
}
} func main(){
var a Student=Student{
Name:"stu01",
Age:18,
Score:92,
}
test(a)
}
可以在动态运行时的时候的到b的很多信息,这就是反射
上面是三种转换 下main是获取值
package main import(
"fmt"
"reflect"
) type Student struct{
Name string
Age int
Score float32
} func test(b interface {}){
t:=reflect.TypeOf(b)
fmt.Println(t) //main.Student 类型 v:=reflect.ValueOf(b)
k:=v.Kind()
fmt.Println(k) //struct类别 iv:=v.Interface()
stu,ok:=iv.(Student)
if ok{
fmt.Printf("%v %T\n",stu,stu)//{stu01 18 92} main.Student
}
} func testInt(b interface{}){
val :=reflect.ValueOf(b)
c:=val.Int() //获取值
fmt.Printf("get value interface{} %d",c)//get value interface{} 1234
} func main(){
var a Student=Student{
Name:"stu01",
Age:18,
Score:92,
}
test(a)
testInt(1234)
}
小结:
1、反射获取具体的了类型
2、转化为具体的值
3、.Int()等获取具体的值
4、才能打印输出值
七、golang中接口、反射的更多相关文章
- golang中的反射reflect详解
先重复一遍反射三定律: 1.反射可以将"接口类型变量"转换为"反射类型对象". 2.反射可以将"反射类型对象"转换为"接口类型变量 ...
- golang中接口interface和struct结构类的分析
再golang中,我们要充分理解interface和struct这两种数据类型.为此,我们需要优先理解type的作用. type是golang语言中定义数据类型的唯一关键字.对于type中的匿名成员和 ...
- golang中的反射
反射操作普通变量 package main import ( "fmt" "reflect" ) func main(){ a := 1 //reflect.T ...
- golang中接口详解
package main import ( "fmt" ) type Sayer interface { say() } type Mover interface { move() ...
- golang中的反射解析结构体标签tag
package main import ( "fmt" "reflect" ) type resume struct { // 反射解析结构体标签tag Nam ...
- golang中接口对象的转型
接口对象的转型有两种方式: 1. 方式一:instance,ok:=接口对象.(实际类型) 如果该接口对象是对应的实际类型,那么instance就是转型之后对象,ok的值为true 配合if...el ...
- golang中接口类型小案例
1. 在项目中实现注册成功之后,向用户发送邮件.微信提醒 package main import "fmt" type IMessage interface { send() b ...
- Golang通脉之反射
什么是反射 官方关于反射定义: Reflection in computing is the ability of a program to examine its own structure, pa ...
- golang(08)接口介绍
原文链接 http://www.limerence2017.com/2019/09/12/golang13/#more 接口简介 golang 中接口是常用的数据结构,接口可以实现like的功能.什么 ...
随机推荐
- 003android初级篇之【转】Android开发中颜色的定义方法
正好用到颜色的定义,但脑子里没有记住具体,转载一篇加强印象 1.使用Color类的常量,如: int color = Color.BLUE; // 创建一个蓝色 是使用Android提供的颜色 int ...
- 制作dos启动u盘
需要准备的工具: 空U盘的U盘HP优盘启动盘格式化工具 链接:https://pan.baidu.com/s/1i59wgUp 密码:l5ke 1.1插入U盘,打开 HP优盘启动盘格式化工具 1. ...
- 使用PHP创建一个socket服务端
与常规web开发不同,使用socket开发可以摆脱http的限制.可自定义协议,使用长连接.PHP代码常驻内存等.学习资料来源于workerman官方视频与文档. 通常创建一个socket服务包括这几 ...
- 第一篇:尽量多的以 const/enum/inline 替代 #define
前言 在面向过程语言,如 C 语言中,#define 非常常见,也确实好用,值得提倡.但在如今面向对象的语言,如 C++ 语言中,#define 就要尽量少用了. 为何在 C++ 中就要少用了呢? 这 ...
- Android-NDK编译
(2013-12-19 21:48:21 其实一切还是先看看官网的好,乱百度浪费时间.... http://developer.android.com/tools/sdk/ndk/index.htm ...
- Codeforces Round #324 (Div. 2) (快速判断素数模板)
蛋疼的比赛,当天忘了做了,做的模拟,太久没怎么做题了,然后C题这么简单的思路却一直卡到死,期间看了下D然后随便猜了下,暴力了下就过了. A.找一个能被t整除的n位数,那么除了<=10以外,其他都 ...
- 洛谷1006==codevs1169
P1006 传纸条 题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法 ...
- Harmonic Value Description(构造题)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission ...
- Python函数参数默认值的陷阱和原理深究(转)
add by zhj: 在Python文档中清楚的说明了默认参数是怎么工作的,如下 "Default parameter values are evaluated when the func ...
- locust基本使用
# coding:utf-8 from locust import HttpLocust,TaskSet,task class BlogDemo(TaskSet): '''用户行为:打开我的博客首页d ...