接口

作者: 陈德华 | 来源:发表于2020-07-18 19:48 被阅读0次

    1、接口

    接口类型 是由一组方法签名定义的集合。

    接口类型的变量可以保存任何实现了这些方法的值。

    注意: 示例代码的 22 行存在一个错误。由于 Abs 方法只为 *Vertex (指针类型)定义,因此 Vertex(值类型)并未实现 Abser。

    2、接口与隐式实现

    类型通过实现一个接口的所有方法来实现该接口。既然无需专门显式声明,也就没有“implements”关键字。

    隐式接口从接口的实现中解耦了定义,这样接口的实现可以出现在任何包中,无需提前准备。

    因此,也就无需在每一个实现上增加新的接口名称,这样同时也鼓励了明确

    3、接口值

    接口也是值。它们可以像其它值一样传递。

    接口值可以用作函数的参数或返回值。

    在内部,接口值可以看做包含值和具体类型的元组:

    (value, type)

    接口值保存了一个具体底层类型的具体值。

    接口值调用方法时会执行其底层类型的同名方法。

    4、底层值为 nil 的接口值

    即便接口内的具体值为 nil,方法仍然会被 nil 接收者调用。

    在一些语言中,这会触发一个空指针异常,但在 Go 中通常会写一些方法来优雅地处理它(如本例中的 M 方法)。

    注意: 保存了 nil 具体值的接口其自身并不为 nil。

    5、nil 接口值

    nil 接口值既不保存值也不保存具体类型。

    为 nil 接口调用方法会产生运行时错误,因为接口的元组内并未包含能够指明该调用哪个 具体 方法的类型。

    6、空接口

    指定了零个方法的接口值被称为 *空接口:*

    interface{}

    空接口可保存任何类型的值。(因为每个类型都至少实现了零个方法。)

    空接口被用来处理未知类型的值。例如,fmt.Print 可接受类型为 interface{} 的任意数量的参数。

    7、类型断言

    类型断言 提供了访问接口值底层具体值的方式。

    t := i.(T)

    该语句断言接口值 i 保存了具体类型 T,并将其底层类型为 T 的值赋予变量 t。

    若 i 并未保存 T 类型的值,该语句就会触发一个恐慌。

    为了 判断 一个接口值是否保存了一个特定的类型,类型断言可返回两个值:其底层值以及一个报告断言是否成功的布尔值。

    t, ok := i.(T)

    若 i 保存了一个 T,那么 t 将会是其底层值,而 ok 为 true。

    否则,ok 将为 false 而 t 将为 T 类型的零值,程序并不会产生恐慌。

    请注意这种语法和读取一个映射时的相同之处。

    8、类型选择

    类型选择 是一种按顺序从几个类型断言中选择分支的结构。

    类型选择与一般的 switch 语句相似,不过类型选择中的 case 为类型(而非值), 它们针对给定接口值所存储的值的类型进行比较。

    switch v := i.(type) {

    case T:

        // v 的类型为 T

    case S:

        // v 的类型为 S

    default:

        // 没有匹配,v 与 i 的类型相同

    }

    类型选择中的声明与类型断言 i.(T) 的语法相同,只是具体类型 T 被替换成了关键字 type。

    此选择语句判断接口值 i 保存的值类型是 T 还是 S。在 T 或 S 的情况下,变量 v 会分别按 T 或 S 类型保存 i 拥有的值。在默认(即没有匹配)的情况下,变量 v 与 i 的接口类型和值相同。

    9、Stringer

    fmt 包中定义的 Stringer 是最普遍的接口之一。

    type Stringer interface {

        String() string

    }

    Stringer 是一个可以用字符串描述自己的类型。fmt 包(还有很多包)都通过此接口来打印值。

    10、

    相关文章

      网友评论

          本文标题:接口

          本文链接:https://www.haomeiwen.com/subject/egvfkktx.html