在Go项目中,组织接口及其实现的惯例是什么?

huangapple go评论85阅读模式
英文:

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

...(为简洁起见,省略了一些存储库和包)...

backtracksolvepermutatesolve都实现了接口solver,所以将它们与接口和其他实现一起放在同一个包中是有意义的。从Java/C#的角度来看,这是一个常见的约定,例如,java.util包含诸如SetMapList等接口,同时还有HashSetHashMapArrayList等实现。

然而,在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).

huangapple
  • 本文由 发表于 2017年6月4日 00:26:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/44346123.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定