一、接口定义

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中接口、反射的更多相关文章

  1. golang中的反射reflect详解

    先重复一遍反射三定律: 1.反射可以将"接口类型变量"转换为"反射类型对象". 2.反射可以将"反射类型对象"转换为"接口类型变量 ...

  2. golang中接口interface和struct结构类的分析

    再golang中,我们要充分理解interface和struct这两种数据类型.为此,我们需要优先理解type的作用. type是golang语言中定义数据类型的唯一关键字.对于type中的匿名成员和 ...

  3. golang中的反射

    反射操作普通变量 package main import ( "fmt" "reflect" ) func main(){ a := 1 //reflect.T ...

  4. golang中接口详解

    package main import ( "fmt" ) type Sayer interface { say() } type Mover interface { move() ...

  5. golang中的反射解析结构体标签tag

    package main import ( "fmt" "reflect" ) type resume struct { // 反射解析结构体标签tag Nam ...

  6. golang中接口对象的转型

    接口对象的转型有两种方式: 1. 方式一:instance,ok:=接口对象.(实际类型) 如果该接口对象是对应的实际类型,那么instance就是转型之后对象,ok的值为true 配合if...el ...

  7. golang中接口类型小案例

    1.  在项目中实现注册成功之后,向用户发送邮件.微信提醒 package main import "fmt" type IMessage interface { send() b ...

  8. Golang通脉之反射

    什么是反射 官方关于反射定义: Reflection in computing is the ability of a program to examine its own structure, pa ...

  9. golang(08)接口介绍

    原文链接 http://www.limerence2017.com/2019/09/12/golang13/#more 接口简介 golang 中接口是常用的数据结构,接口可以实现like的功能.什么 ...

随机推荐

  1. Hibernate每个子类一张表(使用XML文件)实例

    在每个子类一张表的情况下,子类映射表与主键和外键关系与父类映射表相关. 类的<joined-subclass>元素用于使用主键和外键关系将子类与父对象进行映射. 在这个例子中,我们将使用h ...

  2. Eclipse 创建 Java 类

    打开新建 Java 类向导 你可以使用新建 Java 类向导来创建 Java 类,可以通过以下途径打开 Java 类向导: 点击 "File" 菜单并选择 New > Cla ...

  3. MySQL的having子句

    1.定义:having子句对分组的结果集进行进一步的筛选 2.语法:select 字段列表 from 表名称 [where 子句][gruop by 子句] [having 子句]; 3.举例:查询出 ...

  4. MySQL的下载及安装

    前言:不仅要知其然,还要知所以然 MySQL数据库作为关系型数据库中的佼佼者,因其体积小,速度快,成本低,不仅受到了市场的极大追捧,也受到了广大程序员的青睐.接下来,就给大家说一下,MySQL的下载和 ...

  5. 使用 fastjson将字符串转为 list<map<string,object>>

    //先将字符串转为list 集合 json字符串linkConfJson List<Map> linkConf= JSONArray.parseArray(linkConfJson,Map ...

  6. Andriod - 创建自定义控件

    控件和布局的继承结构: 可以看到,我们所用的所有控件都是直接或间接继承自 View的,所用的所有布局都是直接或间接继承自 ViewGroup 的.View 是 Android 中一种最基本的 UI 组 ...

  7. 【穿插】Python基础之文件、文件夹的创建,对上一期代码进行优化

    在上一期妹子图的爬虫教程中,我们将图片都保存在了代码当前目录下,这样并不便于浏览,我们应该将同一个模特的图片都放在一个文件夹中. 今天我们就简单讲一下Python下如何创建文件.文件夹,今后就可以用上 ...

  8. Ants(二分图最佳完美匹配)

    Ants Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6904   Accepted: 2164   Special Ju ...

  9. EasyNVR摄像机网页无插件直播使用过程中问题的自我排查-设备不在线问题的自我排查

    系列背景 由于EasyNVR的受众越来越多,时长会遇到很对类似的问题咨询,之前虽然有写过很多的博文进行技术的或者使用问题的解答,随着客户询问的增多,我发现,要想然客户了解问题和解决问题,往往引导和给一 ...

  10. Redis 单机版本安装

    亲装! 1.linux 系统镜像 redis 版本  使用redis-3.2.8.tar.gz(截止2017年4月的最新稳定版) 在安装之前先安装下redis 需要的环境 wget http://do ...