Go useage of Interface(二)

背景

Hi,Dear All。很快,我们又遇到了interface的另一种用法。上一次,我们是在一个func的参数中可能遇到不同的数据类型,那么这一次呢,我们是根据不同的数据类型可能需要去调用不同的func,那么这种情况下应该怎么办呢🤔。

思考

遇到这个情况,我脑袋里出现的第一个是map,多么完美的key-value的场景,我们接收到一个数据,然后根据数据类型的不同而决定我们使用哪一个方法,所以这里首先引入golang的mapmap是一种很基础的数据结构,这里不多讲。

1
var m map[uint16] interface{} // 定义一个map,key是uint16类型,value是interface类型

Code Now

以下代码,我用猫和狗做了示例,因为有不同的数据类型,所以在stuct中一定要有一个Identifier用于做区分,也就是map中的key,可以理解为数据库表中的主键,作为唯一标识。这里还有一个坑点,就是在golang中,struct中的数值初始化的时候一定要新建一个func然后调用这个func返回struct type才可以被赋值,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type Dog struct {
Identifier uint16 // We use 1
Name string
Voice string
}
func NewDog() Dog {
dog := Dog{}
dog.Identifier = 1
dog.Name = DogName
return dog
}
func main() {
dog := NewDog() // 调用NewDog()返回Dog类型且已赋值
}

在main()函数最开始我们需要initmap,init之后map中类型及对应的func就已经被建立,且对应的方法也已经被调用了,也就是说map中现在存的已经是一个对应的实例化的对象了,这时候我们直接输出即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package main
import (
"fmt"
)
const (
DogName = "Dog"
CatName = "Cat"
)
var m map[uint16] interface{}
func InitMap() {
m = make(map[uint16] interface{})
m[1] = Bark()
m[2] = Miaow()
}
type Dog struct {
Identifier uint16 // We use 1
Name string
Voice string
}
func NewDog() Dog {
dog := Dog{}
dog.Identifier = 1
dog.Name = DogName
return dog
}
type Cat struct {
Identifier uint16 // We use 2
Name string
Voice string
}
func NewCat() Cat {
cat := Cat{}
cat.Identifier = 2
cat.Name = CatName
return cat
}
func Bark() Dog {
dog := NewDog()
dog.Voice = "汪"
return dog
}
func Miaow() Cat {
cat := NewCat()
cat.Voice = "喵"
return cat
}
func main() {
InitMap()
// New a Dog
dog := m[1]
fmt.Println(dog)
// New a Cat
cat := m[2]
fmt.Println(cat)
}

输出结果如下:

WechatIMG42

总结

啊我发现一件事…我明明是为了让你们看着方便才把方法简化成容易理解的玩意,结果怎么发现简化过之后看上去更不容易理解了….=-=MyGod….原谅我。

今天写代码发现了Go的很多坑点,比如struct的初始化一定要定义一个方法,不可以在Struct里进行初始化,然后又发掘了Interface的一个新的用法,虽然用起来感觉很麻烦,但在很多时候似乎这么用比写switch…case方便不少。So,就这样,Thx….