我正在研究Go项目一个月.好的是Go非常高效.但经过一个月的开发,我已经有了数千行代码和许多代码packages.为了避免导入周期对我来说是一个主要的问题,任何时候我遇到导入周期错误,我不知道第一次问题可能在哪里.
Go编译器也只有非常简单的通知,总是不能很好地快速定位问题,如:main.go:7:3: import cycle not allowed.它只会帮助您了解哪个文件可能导致问题,但不会更深入.由于import关系在代码增长时变得越来越复杂,我迫切希望知道如何在Go中更有效地避免导入周期.任何帮助深表感谢.
我在GO中创建了一个restful api,每个方法基本上都与数据库交互.我用来打开数据库连接的具体语句是
db,err := sql.Open("postgres", "user=postgres password=password dbname=dbname sslmode=disable")
if err != nil {
log.Fatal(err)
println(err)
}
Run Code Online (Sandbox Code Playgroud)
这很简单,但问题是,一旦我想在该语句中更改某些内容,那么我必须为具有该语句的所有其他方法更改它.我试图做一个依赖注入或那种性质的东西,以便我可以在一个地方有这个声明或值,只是引用它.我得到一个导入周期不允许错误,但不允许导入周期.这是我的项目结构
我所做的是在Config.go中我写了这个
package Config
const Connect = "user=postgres password=password dbname=dbname sslmode=disable"
Run Code Online (Sandbox Code Playgroud)
然后在Listings.go我把它
package Controllers
import (
"net/http"
"database/sql"
"../Config"
)
func Listing_Expiration(w http.ResponseWriter, r *http.Request) {
db,err := sql.Open("postgres",Config.Connect)
if err != nil {
log.Fatal(err)
println(err)
}
Run Code Online (Sandbox Code Playgroud)
注意我有导入../Config和Config.Connect但是当我编译时,我得到导入循环不允许.我一直试图解决这个问题,但一直无法解决.
所以我要解决这个导入周期。我有以下模式:
view/
- view.go
action/
- action.go
- register.go
Run Code Online (Sandbox Code Playgroud)
总体思路是,操作是在视图上执行的,并由视图执行:
// view.go
type View struct {
Name string
}
// action.go
func ChangeName(v *view.View) {
v.Name = "new name"
}
// register.go
const Register = map[string]func(v *view.View) {
"ChangeName": ChangeName,
}
Run Code Online (Sandbox Code Playgroud)
然后在view.go中调用它:
func (v *View) doThings() {
if action, exists := action.Register["ChangeName"]; exists {
action(v)
}
}
Run Code Online (Sandbox Code Playgroud)
但这会导致一个周期,因为View依赖于Action包,反之亦然。我该如何解决这个周期?有其他方法可以解决此问题吗?