这是golang代码,func newXXX返回一个接口,但为什么它不返回一个struct
type _ABitOfEverythingServer struct {
    v map[string]*examples.ABitOfEverything
    m sync.Mutex
}
type ABitOfEverythingServer interface {
    examples.ABitOfEverythingServiceServer  // interface
    examples.StreamServiceServer            // interface
}
func newABitOfEverythingServer() ABitOfEverythingServer { 
//<-why not return _ABitOfEverythingServer, is it a good way?
    return &_ABitOfEverythingServer{
        v: make(map[string]*examples.ABitOfEverything),
    }
}
Shi*_*hat 10
我不知道上面的代码片段中返回接口是否有任何特殊原因。
但一般来说,返回结构是推荐的方式。还记得Accept interfaces, return structs有人吗?
返回接口无论如何都不会简化模拟,因为客户端可以在需要模拟时定义接口(这是 golang 接口最美丽的事情)。
func newABitOfEverythingServer() *_ABitOfEverythingServer { // <- returning struct ptr
    return &_ABitOfEverythingServer{
        v: make(map[string]*examples.ABitOfEverything),
    }
}
对于上面的重构版本(返回结构),客户端可以简单地定义一个描述其需要的接口,并仅模拟:
type onlyStreamPart interface {
     examples.StreamServiceServer
}
// streamer does not care if the streamServer also
// implements examples.ABitOfEverythingServiceServer
// or not. (Think interface segregation from SOLID)
func streamer(stremServer onlyStreamPart) {
}
// which can be called easily as:
streamer(newABitOfEverythingServer())
这大大简化了测试时的模拟streamer,因为模拟实现不必实现examples.ABitOfEverythingServiceServer接口。
这是来自 Java、C# 等背景的开发人员经常误解的一个问题(其中类型系统是基于名称的,而不是像 Go 中那样是结构化的)。由于在这些语言中,客户端无法修改它接受的接口,因为这需要implements newInterfaceDefinedByClient向需要传递给客户端的所有类添加子句。