首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >包之间的Golang共享配置

包之间的Golang共享配置
EN

Stack Overflow用户
提问于 2016-04-10 17:33:44
回答 3查看 10.1K关注 0票数 15

因此,我刚刚开始学习Go编程语言,并花了几个小时查看示例、参考资料等。正如你们大多数人都会同意的那样,学习一门语言没有比潜心钻研更好的方法了,而这正是我目前正在尝试做的。我正在构建一个Restful风格的web服务。我已经设法让基本的东西运行起来,以及插入到数据库中,注册路由等。然而,在过去的两天里,我一直在努力实现应用程序的配置/属性。这可能只是因为我是新手,我的Go项目架构是完全错误的,所以我在这方面遇到了这么大的困难。这里是我的项目结构

代码语言:javascript
复制
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

代码语言:javascript
复制
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

这是我的main

代码语言:javascript
复制
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))
 }

最后,我的路线就是在这里绘制的

代码语言:javascript
复制
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中的相同配置对象,因为我将需要设置Host、Ports等?我可以再次解析该文件,但我更希望能从一开始就共享该对象。请给我指出正确的方向

EN

回答 3

Stack Overflow用户

发布于 2016-04-18 20:21:46

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

代码语言:javascript
复制
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()

票数 5
EN

Stack Overflow用户

发布于 2016-04-10 20:53:06

现在你想要的只是提供一个变量可以在另一个包中使用,解决方案很简单,记住如果你声明一个变量名以大写字母开头:A-Z,这个变量就可以在go中的另一个包中可见并使用。

因此,您只需将main.go中的config重命名为Config,并将其提取为全局变量:

代码语言:javascript
复制
var Config *models.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))
}

当您想在另一个包中使用它时,只需调用<package name>.Config,包名就是您的main.go所属的包名,在本例中可能是main

票数 2
EN

Stack Overflow用户

发布于 2018-07-31 20:58:20

我已经为此构建了一个库,一个工具箱工厂(单例)和一个不可知的配置解析器(yaml、json和toml),看看这个例子:SpareBox

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36528091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档