File tree Expand file tree Collapse file tree 2 files changed +87
-4
lines changed
Expand file tree Collapse file tree 2 files changed +87
-4
lines changed Original file line number Diff line number Diff line change 22
33## iface 和 eface
44
5- > Written with [ StackEdit] ( https://stackedit.io/ ) .
6- <!-- stackedit_data:
7- eyJoaXN0b3J5IjpbMTkzNzM1ODI0NV19
8- -->
5+ Go 使用 iface 和 eface 来表达 interface。iface 其实就是 interface,这种接口内部是有函数的。
6+
7+ eface 表示 empty interface。
8+
9+ 非空接口:
10+ ``` go
11+ // runtime2.go
12+ type iface struct {
13+ tab *itab
14+ data unsafe.Pointer
15+ }
16+
17+ type itab struct {
18+ inter *interfacetype
19+ _type *_type
20+ hash uint32 // copy of _type.hash. Used for type switches.
21+ _ [4 ]byte
22+ fun [1 ]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
23+ }
24+ ```
25+
26+ 空接口:
27+
28+ ``` go
29+ type eface struct {
30+ _type *_type
31+ data unsafe.Pointer
32+ }
33+ ```
34+
35+ 所以我们可以比较容易地推断出来下面两种 interface 在 Go 内部是怎么表示的:
36+
37+ iface:
38+ ``` go
39+ type Reader interface {
40+ Read ([]byte ) (int , error )
41+ }
42+ ```
43+
44+ eface:
45+ ``` go
46+ var x interface {}
47+ ```
48+
49+ ### iface 适用场景
50+
51+ 在 Go 语言中,我们可以借助 iface,实现传统 OOP 编程中的 DIP(dependency inversion principle),即依赖反转。
52+
53+ ``` go
54+ ┌─────────────────┐
55+ │ business logic │
56+ └─────────────────┘
57+ │
58+ │
59+ │
60+ ┌───────────────────────────────┼───────────────────────────────┐
61+ │ │ │
62+ │ │ │
63+ │ │ │
64+ ▼ ▼ ▼
65+ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
66+ │ RPC │ │ DATABASE │ │ CONFIG_SERVICE │
67+ └─────────────────┘ └─────────────────┘ └─────────────────┘
68+ ```
69+
70+ 上面这样的控制流关系在企业软件中很常见,但如果我们让软件的依赖方向与实际控制流方向一致,很容易导致 RPC、CONFIG_SERVER,DATABASE 的抽象被泄露到上层。例如在业务逻辑中有形如下面的结构体定义:
71+
72+ ``` go
73+ type Person struct {
74+ Age int ` db:"age"`
75+ Name string ` db:"name"`
76+ }
77+ ```
78+
79+ 或者在业务逻辑中有类似下面的字眼:
80+
81+ ``` go
82+ func CreateOrder (order OrderStruct ) {
83+ config := GetConfigFromETCD () // abstraction leak
84+ CalcOrderMinusByConfig (config, order)
85+ SaveOrder ()
86+ }
87+ ```
88+
89+ 业务逻辑不应该知道底层的实现,不应该有形如 db 的 tag,不应该知道配置是从 ETCD 中取出的。
90+
91+ ### eface 适用场景
You can’t perform that action at this time.
0 commit comments