golang中interface接口的深度解析

Golang中Interface接口的深度解析

理解Interface接口

在Golang中,interface被称作为接口,它定义了一种方法集合,但是实现这些方法的具体结构并不在定义时确定,而是在后续具体实现时确定。interface实现了Java、C#等语言中接口的概念,但是与其他语言中的接口不同的是,Golang的interface是隐式实现(implicit),即不需要显式地声明该结构体类型实现了某个接口。

一个interface的定义如下:

type Shape interface {
    Area() float64
    Perimeter() float64
}

以上代码定义了一个Shape接口,其中Area()和Perimeter()分别是该接口的两个方法。其他结构体可以通过实现Area()和Perimeter()方法来实现该接口。

接口还可以嵌套,例如:

type Shape interface {
    Area() float64
    Perimeter() float64
}

type HasColor interface {
    GetColor() string
}

type ColoredShape interface {
    Shape
    HasColor
}

以上代码定义了一个ColoredShape接口,它嵌套了Shape和HasColor两个接口,其中Shape和HasColor的方法都可以被ColoredShape继承。

接口的具体实现

接口的具体实现要求实现该接口中定义的所有方法。例如,以下代码定义了一个Rect矩形结构体,并实现了Shape接口中定义的Area()和Perimeter()方法:

type Rect struct {
    Width  float64
    Height float64
}

func (r Rect) Area() float64 {
    return r.Width * r.Height
}

func (r Rect) Perimeter() float64 {
    return 2 * (r.Width + r.Height)
}

以上代码定义了一个Rect矩形结构体,并实现了Area()和Perimeter()方法。由于该方法集符合Shape接口的方法集,因此Rect结构体就隐式实现了Shape接口。

接口的类型断言

接口类型可以赋值为结构体类型(或其他实现该接口的数据类型),反之亦然。

当我们需要确定接口类型具体是哪个结构体类型时,需要用到类型断言(type assertion)。

var s Shape = Rect{Width: 10, Height: 20}
r, ok := s.(Rect)
if ok {
    fmt.Println(r.Width, r.Height)
}

以上代码定义了一个Shape接口类型的s变量,并将其赋值为Rect{Width: 10, Height: 20},接着进行了类型断言,判断变量s是否是Rect类型,如果是则进行输出。注意,类型断言的第二个返回值ok为bool类型,表示类型断言是否成功。

接口的空接口

在Golang中,所有类型都实现了一个空接口(interface{}),因为空接口不包含任何方法,所以所有类型都与空接口“匹配”,也就是说可以将任何类型的值赋值给空接口变量,例如:

var i interface{}
i = 42
i = "hello, world"
i = Rect{Width: 10, Height: 20}

以上代码演示了将int、string以及Rect结构体类型分别赋值给空接口变量的过程。

接口常见问题及解答

接口的性能问题

在Golang中,接口定义和实现仅仅涉及到包装器和虚拟函数表的使用。这种“使用方式”不会使代码的性能受到负面影响。

接口和类型的关系

在Golang中,接口运作与类型的概念具有某些相似之处。接口表现为“约束”,并且可以隐式转换为不同的类型。这与类型无关,也就是说,接口不是类型。

接口的实际应用是什么?

接口主要用于两个方面:

  1. 表示包装和操作某个功能集的“契约协议”,而不是某个具体实现。
  2. 当一个值需要在多个实现之间进行交互时,该值的接口通常用作与他人交互的“平台”。这种交互可能是基于契约规定的。接口可以让多个实现统一分配,并且降低编译时关联和编译时的静态性。因此,接口可以在代码的不同部分引用并使用,而不需要,针对每种情况进行特定的构建。

示例

下面的示例展示了如何使用接口来表示和操作不同类型的几何形状。

package main

import (
    "fmt"
    "math"
)

type Shape interface {
    Area() float64
    Perimeter() float64
}

type Rectangle struct {
    Width  float64
    Height float64
}

func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

func (r Rectangle) Perimeter() float64 {
    return 2 * (r.Width + r.Height)
}

type Circle struct {
    Radius float64
}

func (c Circle) Area() float64 {
    return math.Pi * c.Radius * c.Radius
}

func (c Circle) Perimeter() float64 {
    return 2 * math.Pi * c.Radius
}

func ShowShapeInfo(shape Shape) {
    fmt.Printf("Shape type: %T, Area: %f, Perimeter: %f\n", shape, shape.Area(), shape.Perimeter())
}

func main() {
    rect := Rectangle{Width: 10, Height: 20}
    circle := Circle{Radius: 5}

    ShowShapeInfo(rect)
    ShowShapeInfo(circle)
}

输出结果如下:

Shape type: main.Rectangle, Area: 200.000000, Perimeter: 60.000000
Shape type: main.Circle, Area: 78.539816, Perimeter: 31.415927

以上代码定义了Shape接口,然后在Rectangle和Circle两个结构体中实现了Area()和Perimeter()方法,并在ShowShapeInfo函数中传入Shape接口类型的参数,最终输出该参数的Area()和Perimeter()方法的结果。

阅读剩余 72%

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:golang中interface接口的深度解析 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • Java自定义注解用法实例小结

    下面我将详细讲解“Java自定义注解用法实例小结”的完整攻略。 1. 自定义注解 Java中的注解是一种元数据,它为我们提供了一种在代码中嵌入元信息的方式。注解可以代码可读性和编译时的检查,而Java中的注解有许多内置注解,我们也可以通过自定义注解来实现更多的功能。 1.1 自定义注解实现 自定义一个注解要用到Java中的 @interface 关键字,通过…

    other 2023年6月25日
    00
  • 超详细的c语言字符串操作函数教程

    超详细的c语言字符串操作函数教程 1. 简介 字符串操作是C语言中经常使用的操作之一。本教程将详细讲解C语言中常用的字符串操作函数,并带有详细的实例说明。 2. 字符串操作函数 2.1. strlen()函数 strlen()函数用于获取字符串的长度,即字符串中字符的个数。这个函数是很常用的。 #include <stdio.h> #includ…

    other 2023年6月20日
    00
  • Android提高Service优先级的方法分析

    Android提高Service优先级的方法分析 介绍 Service是Android中一种用于在后台执行长时间运行操作的组件。然而,默认情况下,Service在系统资源分配上的优先级相对较低,可能会受到系统资源紧张的影响。因此,当我们需要提高Service的优先级时,可以采取一些方法来实现。 本文将详细讲解Android提高Service优先级的方法,并提…

    other 2023年6月28日
    00
  • String的两种初始化方法讲解

    下面我来详细讲解“String的两种初始化方法讲解”。 String的两种初始化方法讲解 方法一:使用字面量初始化 使用字面量初始化字符串是一种很常见的方式。通过将字符串括在双引号””内来创建一个字符串,例如: String str = "hello world"; 这种初始化方式会在内存中创建一个新的字符串对象,其内容和值都是 “hel…

    other 2023年6月20日
    00
  • C#设计模式系列:备忘录模式(Memento)

    C#设计模式系列:备忘录模式(Memento) 备忘录模式是一种行为型设计模式,它允许你将对象的状态保存到备忘录中并在以后的时间点将对象恢复到先前的状态。 适用场景 需要即时保存和恢复内部状态的对象。 当直接访问对象内部状态的成本比通过备忘录进行恢复操作更高时。 需要保留对象状态历史记录的情况,以便回滚操作等。 实现方法 备忘录模式包含三个主要的角色:Ori…

    其他 2023年3月28日
    00
  • beamoff.zip下载

    当然,我很乐意为您提供BeamOff.zip下载的完整攻略。以下是详细的步骤和示例: 步骤1:了解BeamOff.zip BeamOff.zip是一款用于禁用macOS中的BeamSync功能的工具。它可以帮助您提高macOS的性能和稳定性。 步骤2:下载和解压BeamOff.zip 以下是下载和解压BeamOff.zip的示例: 打开BeamOff.zip…

    other 2023年5月6日
    00
  • C++ string格式化输出方式

    C++中的string数据类型可以通过格式化输出方式来输出不同类型的数据。下面是C++ string格式化输出的完整攻略: 1.基本的string格式化输出方式 使用%来指代格式化输出的位置,其中可以使用以下的格式符来输出不同类型的数据: %d:输出整数 %f:输出浮点数 %s:输出字符串 以下代码演示了基本的string格式化输出方式: #include …

    other 2023年6月26日
    00
  • gps坐标(wgs84)转换百度坐标(bd09)python测试

    GPS坐标(WGS84)转换百度坐标(BD09) Python测试 在开发中,我们通常会需要把GPS坐标转换成百度坐标,以便在地图上正确的标注位置信息。本文将介绍如何使用Python实现GPS坐标(WGS84)转换成百度坐标(BD09)的功能。 1. 安装Python第三方库 我们需要安装geohash2和geopy这两个Python库,方便进行坐标转换和计…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部