golang foment是否没有文件结构?
我一直在研究golang以构建一个web应用程序,我喜欢golang的语言和一切,但我很难理解golang中的结构概念。它似乎迫使我没有文件结构,没有文件夹,没有划分,没有分离的关注点。有没有办法以我看不到的方式组织.go文件?到目前为止,文件结构一直是一个令人头痛的问题,这是我在使用这种语言时唯一不好的经历。谢谢大家! 你部分是对的。Go不强制执行任何有关文件和包结构的内容,只是它禁止循环依赖项。这是件好事,因为你可以自由选择最适合你的房间 然而,决定什么是最好的会给你带来负担。我尝试过几种方法,根据我正在做的事情(例如库、命令行工具、服务),我相信不同的方法是最好的 如果您只创建命令行工具,则将根包(存储库的根)设为golang foment是否没有文件结构?,go,Go,我一直在研究golang以构建一个web应用程序,我喜欢golang的语言和一切,但我很难理解golang中的结构概念。它似乎迫使我没有文件结构,没有文件夹,没有划分,没有分离的关注点。有没有办法以我看不到的方式组织.go文件?到目前为止,文件结构一直是一个令人头痛的问题,这是我在使用这种语言时唯一不好的经历。谢谢大家! 你部分是对的。Go不强制执行任何有关文件和包结构的内容,只是它禁止循环依赖项。这是件好事,因为你可以自由选择最适合你的房间 然而,决定什么是最好的会给你带来负担。我尝试过几种方
main
。如果它是一个小工具,那就是你所需要的。您的命令行工具可能会增长,所以您可能希望将一些可以(但不必)在同一存储库中的内容分离到它们自己的内容
如果要创建库,请执行相同的操作,但包名将是库的名称,而不是main
如果您需要组合(作为库和命令行工具都很有用的东西),我会将库代码(库的所有公共内容)放在VCS根目录中,带有潜在的子包和二进制文件的cmd/toolname
谈到web服务,我发现遵循指导原则是最实际的。最好阅读整个博客文章,但简而言之,在VCS根目录中定义您的域,创建
cmd/app
(或多个)作为命令行入口点,并为每个依赖项创建一个包(例如memcache、数据库、http等)。您的子包从不明确地相互依赖,它们只共享根目录下的域定义。这需要一些时间来适应,我仍在根据我的用例进行调整,但到目前为止,它看起来很有希望 你部分是对的。Go不强制执行任何有关文件和包结构的内容,只是它禁止循环依赖项。这是件好事,因为你可以自由选择最适合你的房间
然而,决定什么是最好的会给你带来负担。我尝试过几种方法,根据我正在做的事情(例如库、命令行工具、服务),我相信不同的方法是最好的
如果您只创建命令行工具,则将根包(存储库的根)设为main
。如果它是一个小工具,那就是你所需要的。您的命令行工具可能会增长,所以您可能希望将一些可以(但不必)在同一存储库中的内容分离到它们自己的内容
如果要创建库,请执行相同的操作,但包名将是库的名称,而不是main
如果您需要组合(作为库和命令行工具都很有用的东西),我会将库代码(库的所有公共内容)放在VCS根目录中,带有潜在的子包和二进制文件的cmd/toolname
谈到web服务,我发现遵循指导原则是最实际的。最好阅读整个博客文章,但简而言之,在VCS根目录中定义您的域,创建
cmd/app
(或多个)作为命令行入口点,并为每个依赖项创建一个包(例如memcache、数据库、http等)。您的子包从不明确地相互依赖,它们只共享根目录下的域定义。这需要一些时间来适应,我仍在根据我的用例进行调整,但到目前为止,它看起来很有希望 正如@del boy所说,这取决于你想做什么,我已经多次讨论过这个问题,但在开发golang web应用程序时,更适合我的是将你的包按依赖项划分
- myproject
-- cmd
--- main.go
-- http
--- http.go
-- postgres
--- postgres.go
-- mongodb
--- mongodb.go
myproject.go
myproject.go将包含包含主域或业务模型的接口和结构
例如,您可以使用insidemyproject.go
type User struct {
MongoID bson.ObjectId `bson:"_id,omitempty"`
PostgresID string
Username string
}
还有这样的界面
type UserService interface {
GetUser(username string) (*User, error)
}
现在,在您的http包中,您将处理公开api端点的问题
//Handler represents an HTTP API interface for our app.
type Handler struct {
Router *chi.Mux // you can use whatever router you like
UserService myproject.UserService
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *Request){
//this just a wrapper for the Router ServeHTTP
h.Router.ServeHTTP(w,r)
}
func (h *Handler) someHandler(w http.ResponseWriter, r *Request){
//get the username from the request
//
user := h.UserService.GetUser(username)
}
在postgres.go中,您可以有一个实现用户服务的结构
type PostgresUserService struct {
DB *sql.DB
}
然后实现服务
func (s *PostgresUserService) GetUser(username string) {
//implement the method
}
mongodb也可以做同样的事情
type MongoUserService struct {
Session *mgo.Session
}
func (s *MongoUserService) GetUser(username string) {
//implement the method
}
现在在你的cmd/main.go中,你可以有这样的东西
func main(){
postgresDB, err := postgres.Connect()
mongoSession, err := mongo.Connect()
postgresService := postgres.PostgresUserService{DB: postgresDB}
mongoService := mongo.MongoUserService{Session: mongoSession}
//then pass your services to your http handler
// based on the underlying service your api will act based on the underlying service you passed
myHandler := http.Handler{}
myHandler.UserService = postgresService
}
假设您更改了基础存储,您只需在此处更改它,就不会更改任何内容
这个设计深受启发,我希望你会觉得它很有帮助,正如@del boy所说,这取决于你想做什么,我多次讨论过这个问题,但在开发golang web应用程序时,更适合我的是按依赖项划分包
- myproject
-- cmd
--- main.go
-- http
--- http.go
-- postgres
--- postgres.go
-- mongodb
--- mongodb.go
myproject.go
myproject.go将包含包含主域或业务模型的接口和结构
例如,您可以使用insidemyproject.go
type User struct {
MongoID bson.ObjectId `bson:"_id,omitempty"`
PostgresID string
Username string
}
还有这样的界面
type UserService interface {
GetUser(username string) (*User, error)
}
现在,在您的http包中,您将处理公开api端点的问题
//Handler represents an HTTP API interface for our app.
type Handler struct {
Router *chi.Mux // you can use whatever router you like
UserService myproject.UserService
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *Request){
//this just a wrapper for the Router ServeHTTP
h.Router.ServeHTTP(w,r)
}
func (h *Handler) someHandler(w http.ResponseWriter, r *Request){
//get the username from the request
//
user := h.UserService.GetUser(username)
}
在postgres.go中,您可以有一个实现用户服务的结构
type PostgresUserService struct {
DB *sql.DB
}
然后实现服务
func (s *PostgresUserService) GetUser(username string) {
//implement the method
}
mongodb也可以做同样的事情
type MongoUserService struct {
Session *mgo.Session
}
func (s *MongoUserService) GetUser(username string) {
//implement the method
}
现在在你的cmd/main.go中,你可以有这样的东西
func main(){
postgresDB, err := postgres.Connect()
mongoSession, err := mongo.Connect()
postgresService := postgres.PostgresUserService{DB: postgresDB}
mongoService := mongo.MongoUserService{Session: mongoSession}
//then pass your services to your http handler
// based on the underlying service your api will act based on the underlying service you passed
myHandler := http.Handler{}
myHandler.UserService = postgresService
}
假设您更改了基础存储,您只需在此处更改它,就不会更改任何内容
此设计深受此启发,我希望您会觉得它很有用。您看过吗:?是的,我看过,根据我收集的信息,如果我使用MVC模式,我会