为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 包间共享配置

Golang 包间共享配置

Go
慕运维8079593 2022-01-04 10:32:54
所以我刚刚开始学习 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.gopackage modelsimport (   "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 的相同配置对象,因为我需要设置主机、端口等?我可以再次解析该文件,但我更愿意从一开始就共享该对象。请指出我正确的方向
查看完整描述

3 回答

?
噜噜哒

TA贡献1784条经验 获得超7个赞

我的建议是声明一个全局变量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包,则init()inmodels将在内部的任何代码之前运行main.go,因此该变量Configuration将在使用之前进行初始化。


查看完整回答
反对 回复 2022-01-04
?
炎炎设计

TA贡献1808条经验 获得超4个赞

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


所以,你只需要重命名config你main.go来Config,并提取其作为全局变量:


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在你的情况下。


查看完整回答
反对 回复 2022-01-04
?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

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


查看完整回答
反对 回复 2022-01-04
  • 3 回答
  • 0 关注
  • 237 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信