2016-04-10 29 views
4

因此,我刚开始学习Go编程语言,并花了数小时查看示例,参考资料等。因为你们大多数人会同意,没有更好的方式来学习一门语言,而不是潜入并做出一些事情,这就是我现在正在尝试做的事情。我正在构建一个Restful Web服务。我设法使基本运行以及插入数据库,注册路线等。但是在过去的两天里,我一直在努力实现应用程序配置/属性。这可能就是因为我是新手,我的Go项目架构都是错误的,因此我为什么会遇到这样的困难。这里没有进一步由于是我的项目结构Golang共享软件包之间的配置

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的相同配置对象,因为我需要设置Host,Ports等?我可以再次解析该文件,但我更喜欢是否可以从头开始共享这一个对象。请指点我正确的方向

回答

1

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

所以,你只需要在你的main.goConfig重命名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

+0

感谢您的回答,是的,我知道的大写范围规则。但是,当我想你的解决方案'config'没有被其他的包拾起。因此,我的'main.go'在'package main'中,我将该变量重命名为'Config',然后尝试在'database/dbaccess.go'中引用它。然而,我得到'未解决的参考'似乎没有工作 – MrSSS16

+0

@ MrSSS16,对不起,你还应该声明它是一个全局变量,我的答案已更新。 – starkshang

+0

我在答案中看不到您的更改,并且仍然存在其他程序包无法从'main.go'检测到我的'Config'的问题。所以我在我的主'var Config * models.Config'中声明了,但是我不能从其他包,特别是'database'访问它。 – MrSSS16

1

我会建议在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()

相关问题