如何正确地从Golang的子目录导入包?
我是Golang的新手,我正在尝试让一个简单的RESTAPI应用程序工作 起初,一切都很好,因为我在如何正确地从Golang的子目录导入包?,go,Go,我是Golang的新手,我正在尝试让一个简单的RESTAPI应用程序工作 起初,一切都很好,因为我在main包下的同一目录中有所有代码 但是,现在我正处于一个需要开始将代码重构到子目录和包的阶段。不幸的是,我无法成功编译该应用程序 我的GOPATH设置为:~/.workspace 当前应用程序位于:~/.workspace/src/gitlab.com/myapp/api auth 这就是我当前的代码组织: 这是我的main.go package main import ( "net
main
包下的同一目录中有所有代码
但是,现在我正处于一个需要开始将代码重构到子目录和包的阶段。不幸的是,我无法成功编译该应用程序
我的GOPATH
设置为:~/.workspace
当前应用程序位于:~/.workspace/src/gitlab.com/myapp/api auth
这就是我当前的代码组织:
这是我的main.go
package main
import (
"net/http"
"os"
"strings"
"github.com/gorilla/context"
"github.com/justinas/alice"
"gopkg.in/mgo.v2"
"gitlab.com/myapp/api-auth/middlewares"
)
func main() {
privateKey := []byte(strings.Replace(os.Getenv("JWT_KEY"), "\\n", "\n", -1))
conn, err := mgo.Dial(os.Getenv("MONGO_CONN"))
if err != nil {
panic(err)
}
defer conn.Close()
conn.SetMode(mgo.Monotonic, true)
ctx := appContext{
conn.DB(os.Getenv("MONGO_DB")),
privateKey,
}
err = ctx.db.C("users").EnsureIndex(mgo.Index{
Key: []string{"username"},
Unique: true,
Background: true,
Sparse: false,
})
if err != nil {
panic(err)
}
commonHandlers := alice.New(LoggingHandler, context.ClearHandler, RecoveryHandler, AcceptHandler, ContentTypeHandler)
router := NewRouter()
router.Post("/users", commonHandlers.Append(BodyParserHandler(UserResource{})).ThenFunc(ctx.userCreationHandler))
router.Post("/sessions", commonHandlers.Append(BodyParserHandler(UserResource{})).ThenFunc(ctx.sessionCreationHandler))
http.ListenAndServe(":8080", router)
}
type appContext struct {
db *mgo.Database
privateKey []byte
}
下面是一个中间件accept.go
(其余中间件的构造类似)
这是我从我的应用程序根目录运行go build
时遇到的错误
# gitlab.com/utiliti.es/api-auth
./main.go:11: imported and not used: "gitlab.com/myapp/api-auth/middlewares"
./main.go:42: undefined: LoggingHandler
./main.go:42: undefined: RecoveryHandler
./main.go:42: undefined: AcceptHandler
./main.go:42: undefined: ContentTypeHandler
./main.go:45: undefined: BodyParserHandler
./main.go:46: undefined: BodyParserHandler
限定标识符是使用包名称限定的标识符
前缀包名称和标识符都不能为空
QualifiedIdent = PackageName "." identifier .
限定标识符访问不同包中的标识符,
必须进口。必须导出并声明标识符
在该包的包块中
math.Sin // denotes the Sin function in package math
导入声明声明包含声明的源文件取决于导入包的功能(§程序)
初始化和执行),并允许访问导出的
该包的标识符。导入将命名一个标识符
(PackageName)用于访问和指定
要导入的包
ImportDecl = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
ImportSpec = [ "." | PackageName ] ImportPath .
ImportPath = string_lit .
PackageName用于限定标识符中,以访问导入源文件中包的导出标识符。
它在文件块中声明。如果省略了PackageName,则
默认为在的package子句中指定的标识符
进口包装。如果出现显式句点(.)而不是名称,
在该包的
包块将在导入源文件的文件中声明
块,并且必须在不使用限定符的情况下访问
ImportPath的解释取决于实现,但它通常是已编译文件的完整文件名的子字符串
包,并且可能与已安装包的存储库相关
实现限制:编译器可以仅使用属于Unicode的L,M,
N、 P和S一般类别(不带空格的图形字符)
也可以排除字符!“#$%&'()*,:;?[]^`{|}和
Unicode替换字符U+FFFD
假设我们编译了一个包含package子句package math的包,该子句导出函数Sin,并安装了编译后的
文件中由“lib/math”标识的包
如何在导入包的文件中访问Sin
进口报关单的种类
Import declaration Local name of Sin
import "lib/math" math.Sin
import m "lib/math" m.Sin
import . "lib/math" Sin
导入声明声明导入和导入的包之间的依赖关系。导入包是非法的
自身,直接或间接,或直接导入包
不引用其任何导出的标识符。要导入
只为其副作用(初始化)包装,使用空白
作为显式包名称的标识符:
import _ "lib/math"
错误
./main.go:11: imported and not used: "gitlab.com/myapp/api-auth/middlewares"
说明您在packagemain
中没有使用packageMiddleware
,这是正确的
错误
./main.go:42: undefined: AcceptHandler
说明您没有在包main
中定义AcceptHandler
,这是真的
“限定标识符是使用包名称前缀限定的标识符。限定标识符访问必须导入的不同包中的标识符。”
例如,在包
main
中,使用限定标识符middleware.AcceptHandler
,这是导入“gitlab.com/myapp/api auth/middleware”
的用法,您可以引用符号(函数、变量、类型)通过名称与该包名称之间的间距与其他包进行比较-例如,middleware.AcceptHandler
。这就是为什么它们似乎未定义,而middleware“未使用”的原因。对该语言的新手来说,这是非常有帮助的、深入的解释。
./main.go:42: undefined: AcceptHandler