gpt4 book ai didi

go - 如何从 Golang 的子目录中正确导入包?

转载 作者:IT老高 更新时间:2023-10-28 13:08:14 25 4
gpt4 key购买 nike

我是 Golang 的新手,正在尝试制作一个简单的 REST api 应用程序。

最初,一切都很好,因为我将所有代码都放在 main 包下的同一目录中。

但是,现在我正处于需要开始将代码重构为子目录和包的阶段。不幸的是,我未能成功编译应用程序。

我的 GOPATH 设置为:~/.workspace当前应用位于:~/.workspace/src/gitlab.com/myapp/api-auth

这就是我当前的代码组织方式:

enter image description here

这是我的 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(其余中间件的构造类似)

package middlewares

import "net/http"

// AcceptHandler ensures proper accept headers in requests
func AcceptHandler(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Accept") != "application/vnd.api+json" {
writeError(w, errNotAcceptable)
return
}

next.ServeHTTP(w, r)
}

return http.HandlerFunc(fn)
}

这是我从应用程序的根目录运行 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

最佳答案

The Go Programming Language Specification

Qualified identifiers

A qualified identifier is an identifier qualified with a package name prefix. Both the package name and the identifier must not be blank.

QualifiedIdent = PackageName "." identifier .

A qualified identifier accesses an identifier in a different package, which must be imported. The identifier must be exported and declared in the package block of that package.

math.Sin  // denotes the Sin function in package math

Import declarations

An import declaration states that the source file containing the declaration depends on functionality of the imported package (§Program initialization and execution) and enables access to exported identifiers of that package. The import names an identifier (PackageName) to be used for access and an ImportPath that specifies the package to be imported.

    ImportDecl       = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
ImportSpec = [ "." | PackageName ] ImportPath .
ImportPath = string_lit .

The PackageName is used in qualified identifiers to access exported identifiers of the package within the importing source file. It is declared in the file block. If the PackageName is omitted, it defaults to the identifier specified in the package clause of the imported package. If an explicit period (.) appears instead of a name, all the package's exported identifiers declared in that package's package block will be declared in the importing source file's file block and must be accessed without a qualifier.

The interpretation of the ImportPath is implementation-dependent but it is typically a substring of the full file name of the compiled package and may be relative to a repository of installed packages.

Implementation restriction: A compiler may restrict ImportPaths to non-empty strings using only characters belonging to Unicode's L, M, N, P, and S general categories (the Graphic characters without spaces) and may also exclude the characters !"#$%&'()*,:;<=>?[]^`{|} and the Unicode replacement character U+FFFD.

Assume we have compiled a package containing the package clause package math, which exports function Sin, and installed the compiled package in the file identified by "lib/math". This table illustrates how Sin is accessed in files that import the package after the various types of import declaration.

    Import declaration          Local name of Sin

import "lib/math" math.Sin
import m "lib/math" m.Sin
import . "lib/math" Sin

An import declaration declares a dependency relation between the importing and imported package. It is illegal for a package to import itself, directly or indirectly, or to directly import a package without referring to any of its exported identifiers. To import a package solely for its side-effects (initialization), use the blank identifier as explicit package name:

    import _ "lib/math"

错误

./main.go:11: imported and not used: "gitlab.com/myapp/api-auth/middlewares"

说你没有使用包main中的包middlewares,这是真的。

错误

./main.go:42: undefined: AcceptHandler

表示你没有在main包中定义AcceptHandler,这是真的。

“合格的标识符是带有包名前缀的标识符。合格的标识符访问不同包中的标识符,必须导入。”

例如,在包main中,使用限定标识符middlewares.AcceptHandler,这是一个使用import "gitlab.com/myapp/api-身份验证/中间件”.

关于go - 如何从 Golang 的子目录中正确导入包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35243865/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com