私は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:新しい知識を反映するために、明確化の質問。ビルドタグが上記の問題を引き起こしたと私はかなり確信しています。
例コードが正しく見えます。あなたのコードに 'go vet'を実行してみてください。 – SnoProblem
この問題は再現できません。 '$ GOPATH/src/myapp'では、' go build'を実行し、うまくコンパイルします。あなたは 'go build'をどこで実行していますか? '$ GOPATH'は正しく設定されていますか(正しくビルドするために設定する必要はありませんが、1.9でテストしています)? –
@SnoProblem 'go vet'は何も出力せず、私は本当に困惑していると言わなければなりません。 –