Golang 在包之间共享配置

标签 go gorilla

所以我刚开始学习 Go 编程语言,并且花了几个小时查看示例、引用资料等。正如你们中的大多数人会同意的那样,学习一门语言没有比潜入并做点什么更好的方法了,这就是我目前正在尝试做的事情。我正在构建一个 Restful Web 服务。我已经设法让基础知识运行以及插入数据库、注册路由等。但是在过去的两天里,我一直在努力实现应用程序配置/属性。可能只是因为我是新手,所以我的 Go 项目架构都是错误的,因此为什么我会遇到这样的困难。不用多说,这里是我的项目结构

src
   server
      database
         dbaccess.go
         dbcomm.go
      handling
         handler.go
         handlercomm.go
      models
         config.go
         response.go
         user.go
      routing
         routes.go
      main.go

这是我的 config.go

package models

import (
   "io/ioutil"
   "encoding/json"
)

type Config struct  {
   Db map[string]string `json:"db"`
   Server map[string]string `json:"server"`
}


func NewConfig(fname string) *Config{
   data,err := ioutil.ReadFile(fname)
   if err != nil{
      panic(err)
   }
   config := Config{}
   err = json.Unmarshal(data,&config)
   if err != nil {
   panic(err)
}
return config

这是我的主线

func main(){
    args := os.Args[1:]
    if len(args) == 0{
       fmt.Println("********************\nMust specify a config file   in args\n********************")
    os.Exit(1)
   }

   config := models.NewConfig(args[0])
   port := config.Server["PORT"]

   router := routing.NewRouter()
   fmt.Printf(  "-------------------------------------------------\n"+
        "Listening and Serving on Port %s\n"+
        "-------------------------------------------------",port)

   log.Fatal(http.ListenAndServe(":"+port,router))
 }

最后这是我的路线被映射的地方

type Route struct {
   Name string
   Method string
   Pattern string
   HandlerFunc http.HandlerFunc
}

var routes = []Route{
   Route{
    "signup",
    "POST",
    "/signup",
    handling.PostSignUpUser,
   },

   Route{
    "authenticate",
    "POST",
    "/login",
    handling.PostLogin,
   },
}

func NewRouter() *mux.Router{
 router :=  mux.NewRouter().StrictSlash(true)
 for _,route := range routes{       
    router.Methods(route.Method)
          .Path(route.Pattern)
          .Name(route.Name)
          .Handler(route.HandlerFunc)
}

return router
}

正如您在我的 Main 中看到的,我从一个文件中初始化了相关配置,这很好。但问题是我将如何在数据库包中使用来自 main 的相同配置对象,因为我需要设置主机、端口等?我可以再次解析文件,但如果我可以从一开始就共享一个对象,我会更喜欢。请指出正确的方向

最佳答案

我的建议是在 config.go 中声明一个全局变量并使用 init() 函数对其进行初始化。这样,您知道该变量将始终在任何包导入它时被初始化。这是一些代码:

package models

import (
   "io/ioutil"
   "encoding/json"
)


var (

    Configuration Config 
)


init() {

    args := os.Args[1:]
    if len(args) == 0{
       fmt.Println("********************\nMust specify a config file   in args\n********************")
       os.Exit(1)
   }

   Configuration = NewConfig(args[0]) // configuration initialized here
}

type Config struct  {
   Db map[string]string `json:"db"`
   Server map[string]string `json:"server"`
}


func NewConfig(fname string) *Config{
   data,err := ioutil.ReadFile(fname)
   if err != nil{
      panic(err)
   }
   config := Config{}
   err = json.Unmarshal(data,&config)
   if err != nil {
      panic(err)
   }
   return config
}

var() 将在 init() 之前运行,但 init() 将在 中的代码之前运行包导入它。所以如果 main.go 导入 models 包,那么 models 中的 init() 将在里面的任何代码之前运行main.go 因此变量 Configuration 将在使用前被初始化。

Effective Go explanation of init()

关于Golang 在包之间共享配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36528091/

相关文章:

go - 如何在递归函数中设置mutex和sync.waitgroup?

go - 如何在 Golang 中使用 socket.io 广播图像?

go - Gorilla 工具包的无限重定向循环

mongodb - 从 channel 读取 SIGSEGV : segmentation violation

go - 如何在 golang 中的文本上执行 DL - RNN 模型?

go - 在 Golang 中处理 URL 中的动态参数

Go 无法调用 NewRouter() 函数

session - 想要在客户端发送新请求时获取 session 值

go - 基于 TLS 的 WebSocket : Golang/Gorilla

go - 奇怪的 404 服务器错误 (ListenAndServeTLS)