the-way-to-go day4

接口(interface) 反射 (reflection)

// 定义了接口
type Shaper interface {
    // 接口中定义方法和他的返回值
    // 并不包含代码块
	Area() float32
    
    // Perimeter() float32
}

type Square struct {
	side float32
}

// Square实现了接口的Area()方法
func (sq *Square) Area() float32 {
	return sq.side * sq.side
}

type Rectangel struct {
	w, h float32
}

// Rectangle实现了接口的Area()方法
func (rec *Rectangel) Area() float32{
	return rec.h * rec.w
}

接口是Go实现多态的版本。如果类型没有实现接口的全部方法就会出现编译错误,给Shaper添加方法Perimeter(),编译则会提示错误*Square does not implement Shaper (missing Perimeter method)

接口嵌套接口

type ReadWrite interface {
    Read(b Buffer) bool
    Write(b Buffer) bool
}

type Lock interface {
    Lock()
    Unlock()
}

type File interface {
    ReadWrite
    Lock
    Close()
}

类型断言:检测和转换接口变量类型

判断接口中是否存在类型

type Square struct {
	side float32
}

type Circle struct {
	radius float32
}

type Shaper interface {
	Area() float32
}

// 省略了部分代码
var ateaIntf Shaper
sq1 := &Square{5}

areaIntf = sq1
if t, ok := areaIntf.(*Square); ok {}// ok : true
if t, ok := areaIntf.(*Circle); ok {}// ok : false

其中*必须要有,不然会编译出错

类型判断:tyoe-switch

switch t := areaIntf.(type) {
case *Square:
	fmt.Printf("Type Square %T with value %v\n", t, t)
case *Circle:
	fmt.Printf("Type Circle %T with value %v\n", t, t)
case nil:
	fmt.Printf("nil value: nothing to check?\n")
default:
	fmt.Printf("Unexpected type %T\n", t)
}

测试一个值是否实现了某个接口

type Stringer interface {
    String() string
}

if sv, ok := v.(Stringer); ok {
    fmt.Printf("v implements String(): %s\n", sv.String()) // note: sv, not v
}

判断v是否实现了String接口

方法集与接口

作用于变量上的方法实际上是不区分变量到底是指针还是值的。
Go 语言规范定义了接口方法集的调用规则:

  • 类型 T 的可调用方法集包含接受者为 *T 或 T 的所有方法集
  • 类型 *T 的可调用方法集包含接受者为 *T 的所有方法
  • 类型 *T 的可调用方法集不包含接受者为 T 的方法

空接口

或称为**最小接口 **不包含任何方法,它对实现不做任何要求:

type Any interface {}

类似Java中的所有类的基类:Object

每个interface {}变量在内存中占据两个字长:一个存类型,一个存数据或是指向数据的指针。

可以利用空接口实现通用类型。

type Node struct {
	le *Node
	data interface{}
	ri *Node
}

func NewNode(le, ri *Node) *Node {
	return &Node{le, nil, ri}
}

func(n *Node) SetData(data interface{}) {
	n.data = data
}

func main() {
	root := NewNode(nil, nil)
	root.SetData("Root")
	a := NewNode(nil, nil)
	b := NewNode(nil, nil)
	root.le = a
	root.ri = b
	fmt.Print(root)
}

反射包

反射是用程序检查其所拥有的结构。

提取接口

使得整个设计可以持续演进,类要实现某个接口,只需要在这个类上实现新的方法。

总结

我们总结一下前面看到的:Go 没有类,而是松耦合的类型、方法对接口的实现。

  • 封装通过可见性实现
  • 继承通过组合
  • 多态通过接口实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值