我正在Go lang中编写一个Web服务器,它需要在服务器启动之前将配置文件读入内存。我无法访问Settings
类型,多个变量以及settings.go
中定义的函数。这些需要可以被同一个包中的其他文件访问,但我一直都未定义'错误,表明我有某种范围错误。
下面是一个演示我的问题的最小代码示例。每个文件在第一行定义了// +build go1.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))
}
设定]中
// +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
}
通过在位于go build
的项目目录中运行$GOPATH/src/myapp
,在Fedora 26 Workstation上使用Go v1.8.3进行编译。
错误:
./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
所有上述都是在settings.go中定义的,但据我所知,执行go build
时,我应该将其包含在包中。任何帮助将不胜感激。
项目结构:
myapp/
+- srv/
| +- server.go
| +- settings.go
+- main.go
更新:澄清问题以反映新知识。我相信构建标记会导致上述问题。
答案 0 :(得分:0)
其他软件包中的导出代码必须以软件包名称为前缀。
package foo
func Bar() { ... }
和
package main
import foo
func main() {
foo.Bar()
}