<返回更多

Go语言之接口定义

2023-08-26    程序员技术成长之路
加入收藏

什么是接口

    接口是有一组方法签名组成的类型定义,并表明任何实现了这些方法的类型实例都属于这个接口的实例。接口定义的一种类型系统,用于抽象和封装具体的实现,让代码具有更强的灵活性和可扩展性。

type interfaceName interface {    methodName(argType ReturnType) returnType    //...}

例如,定义一个可以调用三种功能的smartDevice接口:

type smartDevice interface {    playMusic(song string) error    setAlarm(time string) error    makeCall(number string) error}

接口的实现是隐式的,只要一个类型实现了接口中的所有方法,那么它就实现了这个接口。例如,以下类型smartPhone就实现了smartDevice接口:

type smartPhone struct {    name string}
func (p smartPhone) playMusic(song string) error {    // implement playMusic    return nil}
func (p smartPhone) setAlarm(time string) error {    // implement setAlarm    return nil}
func (p smartPhone) makeCall(number string) error {    // implement makeCall    return nil}

在这个例子中,因为 smartPhone 类型实现了 smartDevice 接口中的所有方法,所以我们说 smartPhone 类型实现了 smartDevice 接口。

如何判断是否实现了某接口

if _, ok := x.(T); ok {    // x implements the interface T} else {    // x doesn't implement the interface T}

在这里,T可以是接口类型或非接口类型,如果T是非接口类型,则上述表达式检查x的动态类型是否为T。如果T是接口类型,则检查x的动态类型是否实现了接口T。如果检查成功,ok等于true且v的类型为T;否则ok等于false且v的类型为T的零值。

如何实现多接口的继承

Go语言中的类型(包括自定义类型和内置类型)可以实现多个接口。只要类型的方法满足了多个接口的所有方法,就可以被认为实现了这些接口。

// 定义了一个Worker接口,有Work方法type Worker interface {    Work()}
// 定义了一个Eater接口,有Eat方法type Eater interface {    Eat()}
// 定义了一个Rest接口,有Rest方法type Rest interface {    Rest()}
// 定义了一个Human结构体,有Name属性,Work、Eat、Rest方法type Human struct {    Name string}
func (h Human) Work() {    fmt.Println(h.Name, "is working.")}
func (h Human) Eat() {    fmt.Println(h.Name, "is eating.")}
func (h Human) Rest() {    fmt.Println(h.Name, "is resting.")}
func mAIn() {    mike := Human{"Mike"}
    // 这个地方可以看到,Human结构体实现了Work、Eat和Rest三个接口    var w Worker = mike    var e Eater = mike    var r Rest = mike
    w.Work()    e.Eat()    r.Rest()}

什么是指针和引用

举例:代码如下他们有什么区别

func (h Human) Rest() {    fmt.Println(h.Name, "is resting.")}和func (h *Human) Rest() {    fmt.Println(h.Name, "is resting.")

两种写法的区别在于接收者类型:(h Human) 是值接收者,(h *Human) 是指针接收者。

当使用指针接收者 (h *Human) 时,修改接收者内部的属性将会改变接收者本身,因为在函数内部我们对接收者的操作是对接收者地址进行操作的。

func (h *Human) setName(name string) {    h.Name = name // 这将会改变原对象的Name属性}

而对于值接收者 (h Human),函数内部接收的是接收者的一个副本,即使修改也不会影响到原对象。

func (h Human) setName(name string) {    h.Name = name // 这不会改变原对象的Name属性,只修改副本}

除此之外,值接收者在函数调用时,会对接收者进行一次拷贝,而指针接收者不会。所以,如果接收者是一个较大的结构体时,指针接收者会更为高效。而且,指针接收者也能够处理nil值。

关键词:Go语言      点击(3)
声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多Go语言相关>>>