英文:
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
...(为简洁起见,省略了一些存储库和包)...
backtracksolve
和permutatesolve
都实现了接口solver
,所以将它们与接口和其他实现一起放在同一个包中是有意义的。从Java/C#的角度来看,这是一个常见的约定,例如,java.util
包含诸如Set
、Map
、List
等接口,同时还有HashSet
、HashMap
和ArrayList
等实现。
然而,在Go中,由于它们都实现了func Solve()
并且都在solve
包中,会出现"redeclared exception"的错误。
是否有约定为每个实现创建一个子目录(如下所示),或者有完全不同的做法?
src/
my-repo/
solve/
backtrack/
backtracksolve.go
permutation/
permutatesolve.go
solver.go
英文:
What is the convention for organising interfaces and their implementations in a Go project?
I am new to Go and creating a small project, I currently have this folder structure:
src/
my-repo/
solve/
backtracksolve.go
permutatesolve.go
...
solver.go
... (some repositories and packages omitted for brevity) ...
backtracksolve
and permutatesolve
both implement the interface solver
so it make sense to keep them in the same package as the interface and other implementations of that interface, coming from Java/C# this is a common convention for example, java.util
contains interfaces such as Set
, Map
, List
, while also having implementations such as HashSet
, HashMap
and ArrayList
.
However in Go because they both implement a func Solve()
and both in the package solve
there is redeclared exception
.
Is it the convention to create a sub directory for each implementation (below) or something completely different?
src/
my-repo/
solve/
backtrack/
backtracksolve.go
permutation/
permutatesolve.go
solver.go
答案1
得分: 1
通常,你会定义实现Solver
接口的不同类型,然后在这些类型上定义Solve
函数。
func (s *BackTrackSolver) Solve() { … }
func (s *PermutateSolver) Solve() { … }
由于这些类型具有不同的名称,所以不会发生名称冲突。你可以在Go Playground上尝试它。
关于你的包命名规范问题:我认为一个好的方法是从一个单一的包中开始编写所有的代码,只导出你实际想要暴露给调用者的类型和函数。然后,当你的代码内聚性降低时,你应该开始将代码拆分成多个包。
还可以参考Go博客中的"Organizing Go code"文章,其中的"What to put into a package"部分(阅读时间较短)。
英文:
You would generally define different types that implement your Solver
interface and then define the Solve
function on those types.
func (s *BackTrackSolver) Solve() { … }
func (s *PermutateSolver) Solve() { … }
Because the types have distinct names there is no name clash.
You can try it out online in the go playground.
About your package convention question: I think a good approach is to start with all code in a single package and only export the types and functions you actually want to expose to your callers. Then later when you your code cohesion drops you should start splitting out code into multiple packages.
Also have a look at the "Organizing Go code" article from the go blog, subsection "What to put into a package" (short read).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论