为什么 Go + 构建代码可能会引入范围问题?



我正在用 Go lang 编写一个 Web 服务器,它需要在服务器启动之前将配置文件读入内存。我在访问我的Settings类型、几个变量和一个在settings.go中定义的函数时遇到问题。这些需要被同一包中的其他文件访问,但我不断收到"未定义"错误,表明我有某种范围错误。

下面是一个最小的代码示例,演示了我的问题。每个文件的第一行都定义了// +build go1.8标记。存在这些标记时,编译将失败,并出现如下所述的错误。如果没有这些标记,编译将按预期进行。

主去

// +build go1.8
package main
import (
"myapp/srv"
)
func main() {
srv.StartServer()
}

服务器.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))
}

设置.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 工作站上使用 Go v1.8.3 进行编译,方法是从位于$GOPATH/src/myapp的项目目录中运行go build

错误:

./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

更新:澄清问题以反映新知识。我相当确信构建标签导致了上述问题。

从其他包导出的代码必须以包名称为前缀。

package foo
func Bar() { ... }

package main
import foo
func main() {
foo.Bar() 
}

相关内容

  • 没有找到相关文章

最新更新