2017-09-09 3 views
0

私はGo langにWebサーバーを作成しています。サーバーを起動する前に構成ファイルをメモリーに読み込む必要があります。 settings.goで定義されているSettingsタイプ、いくつかの変数、関数にアクセスするのに問題があります。これらは同じパッケージ内の他のファイルにアクセスできる必要がありますが、私はスコープエラーのいくつかの並べ替えを示唆して、 '未定義の'エラーを取得し続けます。go + buildタグでスコープの問題が発生するのはなぜですか?

以下は、私の問題を示す最小のコード例です。各ファイルには、最初の行に定義された// +build go1.8タグがあります。これらのタグが存在すると、コンパイルは失敗し、以下で説明するエラーが発生します。これらのタグがなければ、コンパイルは期待通りに進行します。ゴーV1.8を試み

main.go

// +build go1.8 
package main 

import (
    "myapp/srv" 
) 

func main() { 
    srv.StartServer() 
} 

server.go

// +build go1.8 
package srv 

import (
    "fmt" 
    "log" 
    "net/http" 
) 

func init() { 
    // read the server configuration file into memory 
    err := ReadConfig(CFGFILE) 
    if err != nil { 
     log.Fatalf("config error: %s", err) 
    } 
} 

func StartServer() { 
    fmt.Println("Starting server!") 
    fmt.Println("Using config file at: " + CFGFILE) 
    fmt.Println("Running on port: " + PORT) 

    fmt.Print(Conf.String()) 

    log.Fatal(http.ListenAndServe(":" + PORT, nil)) 
} 

settings.go

// +build go1.8 
package srv 

import (
    /* Standard library packages */ 
    "encoding/json" 
    "fmt" 
    "io/ioutil" 
) 


/* All settings */ 
type Settings struct { 
    /* General settings */ 
    Title   string // site title 
    Subtitle  string // site subtitle shown on landing page 
} 

// allow printing of runtime config 
func (s Settings) String() string { 
    res, err := json.MarshalIndent(s, "", " ") 
    var ret string 
    if err != nil { 
     ret = "Error in config." 
    } else { 
     ret = string(res) 
    } 
    return fmt.Sprintf("%s", ret) 
} 

// export global settings 
var Conf Settings 
var PORT string = "3000" 
var CFGFILE string = "config.json" 

func ReadConfig(file string) error { 
    if file == "" { 
     fmt.Println("Path to config file cannot be nil!") 
    } 

    buf, err := ioutil.ReadFile(file) 
    if err != nil { 
     fmt.Println(err) 
    } 

    err = json.Unmarshal(buf, &Conf) 

    return err 
} 

コンパイルFedora 26 Workstationのをプロジェクトディレクトリの$GOPATH/src/myappに配置して実行します。

エラー:

./server.go:12: undefined: ReadConfig 
./server.go:12: undefined: CFGFILE 
./server.go:20: undefined: CFGFILE 
./server.go:21: undefined: PORT 
./server.go:23: undefined: Conf in Conf.String 
./server.go:25: undefined: PORT 

上記のすべては、私がgo buildを実行したときに、私の知る限りでは、パッケージに含まれるべきであるしかしsettings.goで定義されて、です。どんな助けもありがとう。

プロジェクト構造

myapp/ 
+- srv/ 
| +- server.go 
| +- settings.go 
+- main.go 

UPDATE:新しい知識を反映するために、明確化の質問。ビルドタグが上記の問題を引き起こしたと私はかなり確信しています。

+0

例コードが正しく見えます。あなたのコードに 'go vet'を実行してみてください。 – SnoProblem

+0

この問題は再現できません。 '$ GOPATH/src/myapp'では、' go build'を実行し、うまくコンパイルします。あなたは 'go build'をどこで実行していますか? '$ GOPATH'は正しく設定されていますか(正しくビルドするために設定する必要はありませんが、1.9でテストしています)? –

+0

@SnoProblem 'go vet'は何も出力せず、私は本当に困惑していると言わなければなりません。 –

答えて

0

他のパッケージからエクスポートされたコードには、パッケージ名の接頭辞を付ける必要があります。

package foo 

func Bar() { ... } 

package main 

import foo 

func main() { 
    foo.Bar() 
} 
+0

これは私の質問に答えません。 2つのソースファイルは、意図的に同じパッケージに属しています。 –

+0

コード例をより明確に更新しました。私の質問は、複数のファイルに分割された私が作成しているカスタムパッケージに関するものです。これらのファイル*は、私の理解では同じパッケージスコープを共有すべきですが、見えません。 –

+0

@Mue、これは事実上正しいですが、それは問題の問題とは関係ありません。私は知っている、質問が入力された直後に書かれている@JimBは、私が知っている – JimB

関連する問題