Go 接口
Go - 接口
Section titled “Go - 接口”在 Go 中,接口(interface)是一种类型,它定义了一组方法签名(method signatures)。接口指定了一个类型必须实现哪些方法才能“满足”(satisfy)或“实现”(implement)该接口。与其他一些语言不同,Go 的接口是隐式满足的(implicitly satisfied)。如果一个类型实现了接口中声明的所有方法,它就自动满足该接口,无需显式使用 implements 关键字。
这种隐式满足的特性使得 Go 的接口非常灵活和强大,促进了松耦合(loose coupling)并实现了多态性(polymorphism)。
/* define an interface */type InterfaceName interface { MethodName1(param1 type1, param2 type2) returnType1 MethodName2() (returnTypeA, returnTypeB) // ... other method signatures}
/* define a struct (or any other named type) */type ConcreteType struct { // fields}
/* implement interface methods for ConcreteType */// Note: The receiver can be a value (ConcreteType) or a pointer (*ConcreteType)func (c ConcreteType) MethodName1(param1 type1, param2 type2) returnType1 { // method implementation return // ... appropriate value}
func (c ConcreteType) MethodName2() (returnTypeA, returnTypeB) { // method implementation return // ... appropriate values}示例:几何图形
Section titled “示例:几何图形”让我们定义一个名为 Shape 的接口,它包含一个 Area() 方法。然后我们将创建实现此接口的 Circle 和 Rectangle 类型。
package main
import ( "fmt" "math")
// Shape interface defines a contract for types that can calculate their area.type Shape interface { Area() float64}
// Circle type with a radius.type Circle struct { Radius float64}
// Rectangle type with width and height.type Rectangle struct { Width, Height float64}
// Circle implements the Shape interface.func (c Circle) Area() float64 { return math.Pi * c.Radius * c.Radius}
// Rectangle implements the Shape interface.func (r Rectangle) Area() float64 { return r.Width * r.Height}
// printArea takes any Shape and prints its area.// This demonstrates polymorphism.func printArea(s Shape) { fmt.Printf("Area of shape: %f\n", s.Area())}
// calculateTotalArea calculates the sum of areas for a slice of Shapes.func calculateTotalArea(shapes []Shape) float64 { totalArea := 0.0 for _, s := range shapes { totalArea += s.Area() } return totalArea}
func main() { circle := Circle{Radius: 5} rectangle := Rectangle{Width: 10, Height: 5}
fmt.Printf("Circle area: %f\n", circle.Area()) // Direct call fmt.Printf("Rectangle area: %f\n", rectangle.Area()) // Direct call
fmt.Println("\nUsing printArea function (polymorphism):") printArea(circle) // Circle satisfies Shape printArea(rectangle) // Rectangle satisfies Shape
shapes := []Shape{ // A slice of Shapes Circle{Radius: 2.5}, Rectangle{Width: 3, Height: 7}, Circle{Radius: 10}, } total := calculateTotalArea(shapes) fmt.Printf("\nTotal area of all shapes: %f\n", total)}编译并执行上述代码后,会产生以下结果:
Circle area: 78.539816Rectangle area: 50.000000
Using printArea function (polymorphism):Area of shape: 78.539816Area of shape: 50.000000
Total area of all shapes: 334.207943空接口:interface{}
Section titled “空接口:interface{}”没有定义任何方法的接口称为空接口(empty interface),写作 interface{}。由于空接口没有方法,任何类型都实现了它。这使得它对于需要处理未知类型值的函数非常有用。然而,要使用底层具体的(concrete)值,你需要进行类型断言(type assertion)或类型开关(type switch)。
func describe(i interface{}) { fmt.Printf("Value: %v, Type: %T\n", i, i)}
// In main():// describe(42)// describe("hello")// describe(true)类型断言和类型开关
Section titled “类型断言和类型开关”在使用接口值时,你通常需要访问底层具体的类型或其特定的方法。这可以通过类型断言(type assertion)或类型开关(type switch)来完成。
类型断言(Type Assertion):value, ok := i.(ConcreteType)
检查接口值 i 是否持有具体的类型 ConcreteType,并将其赋给 value。如果断言成功,ok 为 true。
类型开关(Type Switch):switch v := i.(type) { case ConcreteType1: ... case ConcreteType2: ... }
允许连续进行多个类型断言。
接口是 Go 设计的基石,它使得系统灵活且可扩展。它们在标准库中被广泛使用,并且是编写地道的(idiomatic)Go 代码的关键。