为什么Go + build标签会引入范围问题?

时间:2017-09-09 20:58:55

标签: go build scope global-variables undefined

我正在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

更新:澄清问题以反映新知识。我相信构建标记会导致上述问题。

1 个答案:

答案 0 :(得分:0)

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

package foo

func Bar() { ... }

package main

import foo

func main() {
    foo.Bar() 
}