【Golang高级特性】struct 嵌入 interface
🧩【Golang高级特性】struct 嵌入 interface
2023-8-17
| 2023-10-15
0  |  0 分钟
type
status
date
slug
summary
tags
category
icon
password
Sub-item
Last edited time
Oct 15, 2023 02:42 AM
Parent item
领域
struct 嵌入 interface的作用是,继承默认的接口实现方法,同时允许自定义部分接口实现。

interface的动态类型和静态类型

有如下例子:
对于一个接口类型的变量来说,有一个静态类型动态类型
例如上面的变量 person,赋给它的值可以被叫做它的实际值(也称动态值),而该值的类型可以被叫做这个变量的实际类型(也称动态类型)。
比如,把取址表达式 &Person 的结果值赋给了变量 person值的类型 *Person 就是该变量的动态类型
动态类型这个叫法是相对于静态类型而言的。对于变量 person 来讲,它的静态类型就是 Action并且永远是 Action,但是它的动态类型却会随着赋给它的动态值而变化。比如,只有我把一个 *Person 类型的值赋给变量 person 之后,该变量的动态类型才会是 *Person 。如果还有一个 Action 接口的实现类型 *ET,并且我又把一个此类型的值赋给了 person,那么它的动态类型就会变为 *ET
💡
在给一个接口类型的变量赋予实际的值之前,它的动态类型是不存在的。

struct嵌入interface

一个实现了某个 interface 的 struct 需要实现该 interface 下的所有方法。
但如果在struct中嵌入了一个interface,例如下面Person中嵌入了Action,是可以直接把结构体赋给接口类型的,因为包含了接口方法,但是未实现该方法。
Person 确实实现了Action 的方法,从一个更可视化的角度来看,可以看成:
那么 p.Action.Jump() 究竟指代的位置是什么?其实,只要是任何实现了 Action 接口的任何对象都可以
另外需要注意的一点是上述例子的打印结果:person:size=[16],value=[&{<nil>}],这里说明两点:
  1. 一个 interface 占据的大小是 16 个字节;
  1. 这里 person 的打印结果为 &{<nil>},即 Action 接口的打印值为 nil,注意这里 nil 仅代表字面量上的 nil,而不代表此处 Action 的值为 nil,接口在被实例化时,会被包装一层复杂的数据结构 iface,iface 的实例会包含两个指针,一个是指向类型信息的指针,另一个是指向动态值的指针。这里的类型信息是由另一个专用数据结构的实例承载的,其中包含了动态值的类型,以及使它实现了接口的方法和调用它们的途径等等。因此,这里的 nil 的真正含义是指 Action 实例化后指向动态值的指针为 nil
通过下面这个示例来更清楚的演示细节:
 

应用

把默认实现了Action接口的Somebody,赋给Hero嵌入的接口,Hero自己实现的Jump方法会把默认Jump方法覆盖。
软件开发
  • GoLang
  • 【Golang包】Golang中的Context具体实现【Golang高级特性】接口型函数
    目录