2016-02-06 2 views
3

Я довольно новичок в Golang и пытаюсь сделать простую работу приложения api REST.Как правильно импортировать пакет из подкаталога в Голанге?

Первоначально все было в порядке, так как у меня был весь код в том же каталоге под пакетом 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 
} 

Вот один из миддл eware 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 
+0

Вы ссылаетесь на символы (функции, переменные, типы) из других пакетов по разным именам с этим именем пакета - например. 'Middlewares.AcceptHandler'. Вот почему они кажутся неопределенными, а middlewares «не используется». – elithrar

ответ

6

The Go Programming Language Specification

Qualified identifiers

Квалифицированный идентификатор является идентификатором квалифицирован с именем пакета префикса. И имя пакета, и идентификатор не должны быть пустыми.

QualifiedIdent = PackageName "." identifier . 

Квалифицированный идентификатор обращается идентификатор в другом пакете, , которые должны быть импортированы. Идентификатор должен быть экспортирован и объявлен в пакетный пакет этого пакета.

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

Import declarations

Декларация импорт заявляет, что исходный файл, содержащий декларацию зависит от функциональности импортируемого пакета (§Program инициализации и исполнение) и позволяет получить доступ к экспортируемым идентификаторов этого пакета. Импорт содержит идентификатор (PackageName), который будет использоваться для доступа, и ImportPath, который указывает пакет для импорта.

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

Пакетное имя используется в квалифицированных идентификаторах для доступа к экспортированным идентификаторам пакета в исходном исходном файле. Он объявлен в файловом блоке. Если PackageName опущено, то по умолчанию соответствует идентификатору, указанному в предложении пакета импортированного пакета . Если явный период (.) вместо имени, , все экспортированные идентификаторы пакета, объявленные в пакете пакета этого пакета, будут объявлены в файле исходного файла импортирующего файла и должны быть доступны без квалификатора.

Интерпретация ImportPath зависит от реализации, но обычно это подстрока полного имени файла скомпилированного пакета и может относиться к репозиторию установленных пакетов.

ограничение реализации: компилятор может ограничить ImportPaths для непустых строк, используя только символы, принадлежащие L UNICODE в, M, N, P и S общие категории (персонажи Графические без пробелов) , а также может исключить символы ! "# $% &«() *:; < => []^`{|} и Unicode символ замены U + FFFD

Предположим, мы собрали пакет, содержащий пакет пункт пакета математику?. , который экспортирует функцию Sin и установил скомпилированный пакет в файл, идентифицированный «lib/math». В этой таблице показано, , как осуществляется доступ к Sin i n файлов, которые импортируют пакет после различных типов декларации импорта .

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" 

говорит, что у вас нет использования пакет middlewares в пакете main, что верно.

Ошибка

./main.go:42: undefined: AcceptHandler 

говорит, что вы не определили AcceptHandler в пакете main, это верно.

«Квалифицированный идентификатор - это идентификатор, имеющий префикс имени пакета. Квалифицированный идентификатор обращается к идентификатору в другом пакете, который необходимо импортировать».

Например, в упаковке main используйте квалифицированный идентификатор middlewares.AcceptHandler, который является использованием импорта "gitlab.com/myapp/api-auth/middlewares".

Смежные вопросы