Golang 包间共享配置

所以我刚刚开始学习 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))

 }

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


慕运维8079593
浏览 238回答 3
3回答

噜噜哒

我的建议是声明一个全局变量config.go并使用该init()函数对其进行初始化。这样,您就知道该变量在任何包导入时都会被初始化。这是一些代码:package modelsimport (   "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包,则init()inmodels将在内部的任何代码之前运行main.go,因此该变量Configuration将在使用之前进行初始化。

炎炎设计

现在你想要的只是提供一个可以在另一个包中使用的变量,解决方案很简单,记住如果你声明一个以大写字母开头的变量名:[AZ],这个变量可以在另一个包中可见并使用去。所以,你只需要重命名config你main.go来Config,并提取其作为全局变量:var Config *models.Configfunc main(){args := os.Args[1:]if len(args) == 0{&nbsp; &nbsp;fmt.Println("********************\nMust specify a config file&nbsp; &nbsp;in args\n********************")os.Exit(1)}Config = models.NewConfig(args[0])port := Config.Server["PORT"]router := routing.NewRouter()fmt.Printf(&nbsp; "-------------------------------------------------\n"+&nbsp; &nbsp; "Listening and Serving on Port %s\n"+&nbsp; &nbsp; "-------------------------------------------------",port)log.Fatal(http.ListenAndServe(":"+port,router))}当你想在另一个包中使用它时,只需调用<package name>.Config,包名是你的 main.go 所属的包名,也许main在你的情况下。

肥皂起泡泡

我已经为此构建了一个库,一个工具箱工厂(单例)和一个不可知的配置解析器(yaml、json 和 toml),看看它,看例子:SpareBox
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go