2016-04-10 4 views
4

私はちょうどGoプログラミング言語を学び始め、例、参考文献などを見るのに何時間も費やしました。あなたのほとんどが同意すると思いますが、私は現時点で何をしようとしているのか、何かを掘り起こして何かを作るよりも、言語を学ぶ良い方法はありません。私は穏やかなWebサービスを構築しています。私は、dbに挿入するだけでなく、ルートを登録するなどの基本を実行することができました。しかし、過去2日間、私はアプリケーション設定/プロパティを実装するのに苦労してきました。それはちょうど私が初心者ですので、私の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 
} 

私のメインで見ることができるように、関連する設定をファイルから初期化します。しかし、問題は、ホスト、ポートなどを設定する必要があるので、データベースパッケージのメインから同じ設定オブジェクトを使用する方法はどうですか?私は再びファイルを解析することができますが、最初からそのオブジェクトを共有することができれば好きです。

答えて

1

これで、変数を別のパッケージで使用できるようにしたいのですが、解決方法は簡単です。変数名が大文字で始まると宣言すると、[AZ]この変数は、表示され、別のパッケージで使用できます。

だから、あなただけのConfigにごmain.goconfigの名前を変更し、グローバル変数として、それを抽出する必要があります。

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'にあります。私は、 'database/dbaccess.go'でそれを参照しようとして、変数を' Config'にリネームしました。しかし、私は '未解決の参照を取得する'のように動作しませんでした – MrSSS16

+0

@ MrSSS16、申し訳ありません、あなたはまた、グローバル変数として宣言する必要があります、私の答えは更新されました。 – starkshang

+0

答えにあなたの変更が表示されず、他のパッケージが 'main.go'の' Config'を検出できない場合と同じ問題があります。だから私は主な 'var Config * models.Config'で宣言しましたが、他のパッケージ、特に'データベース 'からこれをアクセスすることはできません。 – 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.gomodelsパッケージをインポートした場合、modelsinit()main.goのコードの前に実行され、したがって変数Configurationは使用前に初期化されます。

Effective Go explanation of init()

関連する問題