我了解这个问题,根据这里的答案。但是,我确实需要帮助或更详细的代码解释来克服它。
我的情况是:我曾经把模型和控制器分开,在我的模型包中有一个datastore.go文件,其中包含所有模型函数的接口:
package models
type DSDatabase interface {
CreateUser(ctx context.Context, username string, password []byte) (*datastore.Key, error)
// More model functions
}
type datastoreDB struct {
client *datastore.Client
}
var (
DB DSDatabase
_ DSDatabase = &datastoreDB{}
)
func init() {
// init datastore
}
之前的代码都在models包里,所以我的控制器包中的函数可以自由地调用models.DB.CreateUser(ctx, "username", []byte("password"))
.
现在,我决定将所有上述代码移动到一个名为datastore
的包中,而CreateUser
的模型位于user
包中。换句话说,package user
现在包含了控制器和模型函数,其中控制器相关的函数依赖于datastore
包,而DSDatabase
接口则依赖于user
模型函数。
我真的很感激能够帮助我解决如何克服导入循环问题,同时保持DSDatastore
接口与其他包(如home
和user
)分离。
如果以上内容不够清晰,请参考以下代码:
package datastore
import (
"github.com/username/projectname/user"
)
type DSDatabase interface {
user.CreateUser(ctx context.Context, username string, passwoUserRegister(ctx context.Context, username string, password []byte) (*datastore.Key, error)
}
...
在我的
user
包中,我有一个与控制器相关的文件,其中包含以下内容:package user
import (
"github.com/username/projectname/datastore"
)
func CreateUserPOST(w http.ResponseWriter, r *http.Request) {
// get formdata and such
datastore.DB.CreateUser(ctx, "username", []byte("password"))
}
另一个与模型相关的文件中,我有:
package user
import (
"github.com/username/projectname/datastore"
)
func (db *datastore.datastoreDB) CreateUser(ctx context.Context, username string) (*User, error) {
key := datastore.NameKey("User", username, nil)
var user User
err := db.client.Get(ctx, key, &user)
if err != nil {
return nil, err
}
return &user, nil
}
当然,这会导致一个循环引用问题,我很遗憾无法想出如何解决它...
models
和controllers
包中没有任何关联的所有函数分开,而且建议我将与users
相关的所有内容放在一起,以避免出现controllers/user
和models/user
这样的目录,这对我来说是有意义的。 - fisker