因此,我刚刚开始学习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这是我的main
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等?我可以再次解析该文件,但我更希望能从一开始就共享该对象。请给我指出正确的方向
发布于 2016-04-18 20:21:46
我建议在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之前将对其进行初始化。
发布于 2016-04-10 20:53:06
现在你想要的只是提供一个变量可以在另一个包中使用,解决方案很简单,记住如果你声明一个变量名以大写字母开头:A-Z,这个变量就可以在go中的另一个包中可见并使用。
因此,您只需将main.go中的config重命名为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。
发布于 2018-07-31 20:58:20
我已经为此构建了一个库,一个工具箱工厂(单例)和一个不可知的配置解析器(yaml、json和toml),看看这个例子:SpareBox
https://stackoverflow.com/questions/36528091
复制相似问题