为什么java需要spring这么大的框架去做这么简单一件事情呢,主要还是因为java只有类,就算是传接口,也无法避免直接依赖,因为你的真正依赖还是得先去显式实现接口,所以需要用反射一个个对象去查才能完全分离依赖。go天然自带鸭子类型,不需要显式实现接口,只需要实现所有方法就可以被考虑为已经实现了接口,就是说你可以跑可以叫可以游泳你就是只鸭子。为什么说go不需要框架去实现di,可以举个例子说一下。还是一个person类,你需要一个cloth类,你只需要提供一个很小的接口,规定这个衣服得有布料,得有眼色,得能穿身上就行,然后传到person构造器里(类比java用spring的话,定义一个衣服接口,标记上是个bean,然后把在person类里自动注入一个cloth的接口)然后就不需要去管这个衣服到底是什么衣服了,只要是有那几个特征的就是衣服,测试的时候可以直接mock或者不穿,在真正注入(实际上要让人初始化)的时候可以在最外层注入(很多go项目会在main里面做最后的注入,不管这个类有多深),这样的话就完全避免了各个类或者说结构体直接的耦合。当然,spring或者dig这种框架也可以做到一点go原生做不到的事情,就是自动注入,你到最后还是得初始化一个类然后把各个真正依赖初始化然后写到构造器(你最后还是得挑一件衣服给这个person,但是有了框架的话,框架帮你挑,而且不会影响person身上别的装饰)。当然,我个人是觉得用框架只会增加复杂度,di框架最直接的side effect就是让原本的compiler time error变成了runtime error了,而且很难做追踪。一个好的go项目本身就不可能有很大的依赖树,你可以把所有不稳定的因素全部做抽象
依赖注入这种设计模式是从面向对象这种语言上被发现的,Go是偏函数式的编程语言,你要说它不是面象对象吧,它又有接口机制,这么说吧,你可以在GO上面实现依赖注入,但是用起来很麻烦,因为它有指针这种东西,所以实现起来很啰嗦且复杂,大型项目还是需要使用传统面向对象语言来做的,GO更适合为微服务这种架构去编写代码。因为公司就招了两个GO来写自研项目。一个模块拆一个服务出来,工作量多不说,维护起来也麻烦。