Go语言接口interface

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
type A interface {
ShowA() int
}

type B interface {
ShowB() int
}

type Work struct {
i int
}

func (w Work) ShowA() int {
return w.i + 10
}

func (w Work) ShowB() int {
return w.i + 20
}

func main() {
var a A = Work{3}
s := a.(Work)
fmt.Println(s.ShowA())
fmt.Println(s.ShowB())
}
  1. type A interface { ShowA() int } 定义了一个名为A的接口,这个接口要求实现它的类型必须有一个方法ShowA,并且这个方法返回一个整数。
  2. type B interface { ShowB() int } 定义了一个名为B的接口,与A接口类似,要求实现它的类型必须有一个方法ShowB,也返回一个整数。
  3. type Work struct { i int } 定义了一个名为Work的结构体,这个结构体包含一个整数字段i
  4. 这是Work结构体的一个方法。因为它满足了A接口的要求(即拥有ShowA()方法),所以我们可以说Work实现了A接口。
  5. 同样,这是Work结构体的另一个方法。它满足了B接口的要求,所以Work也实现了B接口。
  6. main函数中,首先声明了一个A接口类型的变量a并将其初始化为Work结构体的一个实例,其i字段的值为3。接着,使用类型断言a.(Work),我们将a转换回Work类型,并将结果存储在s变量中。最后,使用fmt.Println打印sShowA()ShowB()方法的返回值。根据方法的定义,这两个方法分别返回3+10=133+20=23

总结:这段代码展示了如何定义和使用接口、结构体以及如何在它们之间进行转换。在这里,Work结构体实现了两个接口AB

为什么可以声明了一个A接口类型的变量a并将其初始化为Work结构体的一个实例?

这涉及到Go语言中接口的工作方式。

在Go中,接口不是直接声明它们需要哪些字段,而是声明需要哪些方法。任何类型只要实现了接口声明的所有方法,就被认为实现了该接口,不需要明确地声明它实现了该接口。

在给定的代码中,A接口声明了一个方法ShowA() intWork结构体实现了这个方法。因此,我们可以说Work实现了A接口。这就是为什么你可以声明一个A接口类型的变量并将其初始化为Work结构体实例的原因。

这样做的好处是,你可以为不同的类型定义相同的方法,并且所有这些类型都可以赋值给这个接口类型的变量。这在多态和设计模式中是非常有用的,因为你可以编写接受接口类型参数的函数,然后在运行时传入任何实现了该接口的类型。

实现了某个接口的意义何在?可以写个例子供我理解吗?

实现某个接口的意义主要在于多态和代码的解耦。当你定义一个接口,你其实是定义了一个行为的契约,而不是具体的实现。这意味着任何满足这个契约的类型都可以被用在期望该接口的地方。这为我们提供了一种编写灵活、可插拔和易于维护的代码的方式。

让我给你一个简单的例子来说明这个概念:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package main

import "fmt"

// 定义一个 Animal 接口,要求实现 SayHello 方法
type Animal interface {
SayHello() string
}

// 实现一个 Dog 类型,满足 Animal 接口
type Dog struct{}

func (d Dog) SayHello() string {
return "Woof!"
}

// 实现一个 Cat 类型,满足 Animal 接口
type Cat struct{}

func (c Cat) SayHello() string {
return "Meow!"
}

// 这个函数接受 Animal 接口类型的参数,因此可以接受任何满足 Animal 接口的类型
func Introduce(a Animal) {
fmt.Println("The animal says:", a.SayHello())
}

func main() {
d := Dog{}
c := Cat{}

Introduce(d) // 输出: The animal says: Woof!
Introduce(c) // 输出: The animal says: Meow!
}

在上面的代码中,Animal接口定义了一个行为SayHelloDogCat两个结构体都实现了这个接口。因此,我们可以在Introduce函数中,不关心具体的动物类型,只关心它们都满足Animal接口。

这为我们提供了极大的灵活性。例如,如果未来我们想添加一个新的动物类型,只需要确保它实现了SayHello方法,然后就可以直接使用Introduce函数来介绍它,而不需要修改Introduce函数的代码。

这种方式允许我们将具体的实现细节(如DogCat的行为)与使用这些实现的代码(如Introduce函数)分开,达到了解耦的目的。

作者

JIeJaitt

发布于

2021-10-04

更新于

2023-10-31

许可协议

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×