Go_Web编程书中的部分精简笔记(go入门学习)-04

2.6 interface

interface 类型定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了此接口。

interface 可以被任意的对象实现,同理一个对象可以实现任意多个interface.

interface

现 interface 就是一组抽象方法的集合,它必须由其他非 interface类型实现,而不能自我实现。

一般就是先定义一个结构体----->>>>然后让该结构体实现一定的方法(method)----->>>把实现的方法定义在一个interface里面

----->>>>如果一个对象实现了interface里面全部的方法就是实现了该接口----->>>此时定义一个interface的变量我们就可以将

定义好的结构体变量的值赋值给接口变量------>>>再调用对应的方法

这个时候我们定义interface 变量的silce就可以把这些接口的值保存在silce。

然后我们可以遍历切片里面的对象调用同一个方法

x[0], x[1], x[2] = paul, sam, mike
 for _, value := range x{
 value.SayHi()
 } 
空interface

每一个类型都实现了空接口所以每一种类型都能调用空接口,interface 在我们需要存储任意类型的数值的时候相当有用,因为它可以存储任意类型的数值。

一个函数把 interface{}作为参数,那么他可以接受任意类型的值作为参数,如果一个函数 返回 interface{},那么也就可以返回任意类型的值

interface 函数参数

通过定义 interface 参数,让函数接受各种类型的参数。

interface 变量存储的类型

判断interface变量存储的类型方法:

• Comma-ok 断言

Go 语言里面有一个语法,可以直接判断是否是该类型的变量: value, ok = element.(T),

这里 value 就是变量的值,ok 是一个 bool 类型,element 是 interface 变量,T 是断言的类

型。

如果 element 里面确实存储了 T 类型的数值,那么 ok 返回 true,否则返回 false。

• switch 测试

switch value := element.(type)

==特别注意:==element.(type)语法不能在 switch 外的任何逻辑里面使用,如果你要在 switch 外面判断一个类型就使用 comma-ok。

嵌入 interface

源码包 container/heap 里面有这样的一个定义

type Interface interface {
 sort.Interface //嵌入字段 sort.Interface
 Push(x interface{}) //a Push method to push elements into the 
heap
 Pop() interface{} //a Pop elements that pops elements from the 
heap
}
嵌入字段 sort.Interface 所包含的方法
type Interface interface {
 // Len is the number of elements in the collection.
 Len() int
 // Less returns whether the element with index i should sort
 // before the element with index j.
 Less(i, j int) bool
 // Swap swaps the elements with indexes i and j.
 Swap(i, j int)
}
反射(浅入未完)

Go 语言实现了反射,所谓反射就是动态运行时的状态。我们一般用到的包是 reflect 包。

使用 reflect 一般分成三步:

1.要去反射是一个类型的值(这些值都实现 了空 interface),首先需要把它转化成 reflect 对象(reflect.Type 或者 reflect.Value,根据不

同的情况调用不同的函数)。

t := reflect.TypeOf(i) //得到类型的元数据,通过 t 我们能获取类型定义里面的所有元素
v := reflect.ValueOf(i) //得到实际的值,通过 v 我们获取存储在里面的值,还可以去改变值

转化为 reflect 对象之后我们就可以进行一些操作了,也就是将 reflect 对象转化成相应的值,

例如

tag := t.Elem().Field(0).Tag //获取定义在 struct 里面的标签

name := v.Elem().Field(0).String() //获取存储在第一个字段里面的值

获取反射值能返回相应的类型和数值

var x float64 = 3.4

// 获取结构体实例的反射类型对象
v := reflect.ValueOf(x)

fmt.Println("type:", v.Type())

fmt.Println("kind is float64:", v.Kind() == reflect.Float64)

fmt.Println("value:", v.Float())

最后,反射的话,那么反射的字段必须是可修改的,我们前面学习过传值和传引用,这个

里面也是一样的道理,反射的字段必须是可读写的意思是,如果下面这样写,那么会发生

错误

var x float64 = 3.4

v := reflect.ValueOf(x)

v.SetFloat(7.1)

如果要修改相应的值,必须这样写

var x float64 = 3.4

p := reflect.ValueOf(&x)

v := p.Elem()//获取类型元素

v.SetFloat(7.1)

上面只是对反射的简单介绍,更深入的理解还需要自己在编程中不断的实践。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

newbie_______

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值