为何要使用Interface
GO有实现泛型吗?没有,以下为官方回答:
Why does Go not have generic types? Generics may well be added at some point. We don’t feel an urgency for them.Generics are convenient but they come at a cost in complexity in the type system and run-time… Meanwhile, Go’s built-in maps and slices, plus the ability to use the empty interface to construct containers mean in many cases it is possible to write code that does what generics would enable, if less smoothly.
简而言之,官方认为虽然泛型很赞,但会使语言设计复杂度提升,所以不打算支持。当然,方法总比困难多,下图也不失为一种不怎么优雅的办法。

除此之外有其他办法吗?有,Go官方也提及,可以暂时先用Interface顶上,Interface可以作为胶水层或抽象层,起到抽象和适配的作用。
Interface的概念
Interface是一组方法签名的集合,由于Go的Interface是非侵入式设计,一个具体类型实现接口不需要在语法上显式地声明,只要具体类型的方法集是接口方法集的超集,就代表该类型实现了接口,编译器在编译时会进行方法集的校验。接口是没有具体实现逻辑的,也不能定义字段。
上述字面的概念可能有点绕,直接通过代码来看会比较直观:
以下为运行结果:
Interface如何支持泛型
在基础概念中,我们了解到,当有多个struct实现一个interface时,可以将interface作为参数,适配多个struct。在上述基础上,我们可以得到一个泛型的办法,接口作为参数来执行上层的逻辑。
具体一点来说,也就是如果是在实现一个服务时,对于不同场景,可以将其共同特征抽象出来,在一个interface中声明,然后给不同的场景定义其特定的struct,上层的逻辑可以通过传入interface来执行,特化则通过struct实现对应的方法,从而达到一定程度的泛型。
举例,我们可能在一个服务中都会用到Key值,但不同的场景,计算Key值的方法可能是不一样的,可以通过如下方法来实现:
GO还有另一种弥补没有泛型的办法,通过空接口来实现泛型。
只要一个类型所实现的方法集是某个接口的超集,则可以认为这个类型实现了这个接口。当一个接口的方法为空,则意味,所有的类型都实现了这个接口,这是一个很方便的设定,类似C语言的void *。如果一个函数需要接收任意类型的参数,参数类型可以使用空interface,并在此基础上搭配reflect进行处理,可以一定程度上达到范型的作用。
举例:
以上个人理解,通过接口+反射机制,基本能搭配出足够的花样来满足泛型编程,另GO的2.0版本已经将泛型提上了日程,想来到时可以不用如此纠结。
参考: