Go 接口

在 Go 编程中,我们使用接口来存储一组没有实现的方法。也就是说,接口的方法没有方法体。例如,

type Shape interface {
  area() float32
  perimeter() float32
}

在这里,Shape 是一个接口,它有两个方法:area()perimeter()。可以看到,这两个方法只有方法签名,没有任何实现。


Go 接口的实现

如果你想知道,如果接口中的方法没有实现,它有什么用。

嗯,要使用接口,我们首先需要用一个类型(struct)来实现它。要实现接口,struct 必须为接口的所有方法提供实现。例如,

package main 
import "fmt"

// interface
type Shape interface {
  area() float32
}

 // struct to implement interface
type Rectangle struct {
  length, breadth float32
}

// use struct to implement area() of interface
func (r Rectangle) area() float32 {
  return r.length * r.breadth
}

// access method of the interface
func calculate(s Shape) {
  fmt.Println("Area:", s.area())
}

// main function
func main() {
 
  // assigns value to struct members
  rect := Rectangle{7, 4}

  // call calculate() with struct variable rect
  calculate(rect)
    
}

输出

Area: 28

让我们看看这个程序是如何工作的

接口实现工作原理

在上面的例子中,我们创建了一个名为 Shape 的接口,其中有一个方法 area()。在这里,我们试图用 Rectangle struct 来实现这个接口。

type Rectangle struct {
  length, breadth float32
}

现在,为了实现接口,我们提供了 getArea() 的实现。

func (r Rectangle) area() float32 {
  return r.length * r.breadth
}

为了访问这个方法,我们创建了一个 calculate() 方法

// access method of the interface
func calculate(s Shape) {
  fmt.Println("Area: ", s.area())
}

在这里,该方法接受一个 Shape 类型的变量,名为 s,并使用它来调用 area() 方法。

由于该结构实现了接口,我们使用了结构变量调用了 calculate()

rect := Rectangle{7, 4}
calculate(rect)

用多个 Struct 实现 Go 接口

在 Go 中,一个接口也可以被多个 struct 实现。例如,

package main 
import "fmt"

// interface
type Shape interface {
  area() float32
}

 // Rectangle struct implements the interface
type Rectangle struct {
  length, breadth float32
}

// Rectangle provides implementation for area()
func (r Rectangle) area() float32 {
  return r.length * r.breadth
}

// Triangle struct implements the interface
type Triangle struct {
  base, height float32       
}

// Triangle provides implementation for area()
func (t Triangle) area() float32 {
    return 0.5 * t.base * t.height
}

// access method of the interface
func calculate(s Shape) float32 {
  return s.area()
}

// main function
func main() {
 
  // assigns value to struct members
  r := Rectangle{7, 4}
  t := Triangle{8, 12}
 
  // call calculate() with struct variable rect 
  rectangleArea := calculate(r)
  fmt.Println("Area of Rectangle:", rectangleArea)
  
  triangleArea := calculate(t)
  fmt.Println("Area of Triangle:", triangleArea)

}

输出

Area of Rectangle: 28
Area of Rectangle: 48

在上面的例子中,我们使用了两个 struct:RectangleTriangle 来实现 Shape 接口。

和以前一样,这两个 struct 都为 area() 方法提供了实现。

这次,calculate() 使用接口 Shape 调用 area() 并返回它。

所以,对于第一个调用 calculate(r),该方法将调用 Rectanglearea() 方法实现。同样,对于 calculate(t),该方法将调用 Trianglearea() 方法实现。


如果 struct 没有实现接口的所有方法会怎样?

当一个 struct 实现一个接口时,它应该为接口的所有方法提供实现。如果它未能实现任何方法,我们将收到一个错误。例如,

package main 
import "fmt"

// interface
type Shape interface {
  area() float32
  perimeter() float32
}

 // Rectangle struct implements the interface
type Rectangle struct {
  length, breadth float32
}

// Rectangle provides implementation for area()
func (r Rectangle) area() float32 {
  return r.length * r.breadth
}

// access method of the interface
func calculate(s Shape) float32 {
  return s.area()
}

// main function
func main() {
 
  // assigns value to struct members
  r := Rectangle{7, 4}

  // call calculate() with struct variable rect 
  rectangleArea := calculate(r)
  fmt.Println("Area of Rectangle:", rectangleArea)
}

输出

cannot use r (type Rectangle) as type Shape in argument to calculate:
	Rectangle does not implement Shape (missing perimeter method)

在上面的例子中,Shape 接口有两个方法:area()perimeter()。在这里,我们试图用 Rectangle struct 来实现接口。

但是,该 struct 只提供了 area() 的实现。由于该 struct 没有实现接口的所有方法,因此我们得到了一个错误。

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战