在 Go 项目中组织接口及其实现的约定是什么?

What is the convention for organising interfaces and their implementations in a Go project?

在 Go 项目中组织接口及其实现的约定是什么?

我是 Go 的新手,正在创建一个小项目,我目前的文件夹结构是这样的:

src/
    my-repo/
        solve/
            backtracksolve.go
            permutatesolve.go
            ...
            solver.go

... (some repositories and packages omitted for brevity) ...

backtracksolvepermutatesolve 都实现了接口 solver 因此将它们与接口和该接口的其他实现放在同一个包中是有意义的,来自 Java/C# 这是一个常见的约定,例如,java.util 包含 SetMapList 等接口,同时还具有 HashSet 等实现, HashMapArrayList.

但是在 Go 中因为它们都实现了 func Solve() 并且在 package solve 中都有 redeclared exception.

是为每个实现(下面)创建一个子目录还是完全不同的东西?

src/
    my-repo/
        solve/
            backtrack/
                backtracksolve.go
            permutation/
                permutatesolve.go

            solver.go

您通常会定义实现 Solver 接口的不同类型,然后在这些类型上定义 Solve 函数。

func (s *BackTrackSolver) Solve() { … }
func (s *PermutateSolver) Solve() { … }

因为类型具有不同的名称,所以没有名称冲突。 您可以在 the go playground.

在线试用

关于您的包约定问题:我认为一个好的方法是从单个包中的所有代码开始,并且仅导出您实际想要向调用者公开的类型和函数。然后当你的 code cohesion 掉线时,你应该开始将代码分成多个包。

另请参阅 go blog 中的 "Organizing Go code" 文章,第 "What to put into a package" 小节(简读)。