Як імпортувати локальні пакети в go?


90

Я новачок у роботі над прикладом коду, який я хочу локалізувати.

В оригінальній main.goзаяві про імпорт було:

 import (
    "log"
    "net/http"
    "github.com/foo/bar/myapp/common"
    "github.com/foo/bar/myapp/routers"
)

Зараз у мене є commonі routersупаковка/home/me/go/src/myapp

Тож я перетворив оператор імпорту на:

import (
    "log"
    "net/http"
    "./common"
    "./routers"
)

Але коли я запускаю, go install myappя отримую такі помилки:

can't load package: /home/me/go/src/myapp/main.go:7:3: local import "./common" in non-local package

Крім того , коли я використовую commonі routersзамість того , щоб ./commonі ./routersв заяві імпорту, я отримую:

myapp/main.go:7:3: cannot find package "common" in any of:
    /usr/local/go/src/common (from $GOROOT)
    /home/me/go/src/common (from $GOPATH)
myapp/main.go:8:2: cannot find package "routers" in any of:
    /usr/local/go/src/routers (from $GOROOT)
    /home/me/go/src/routers (from $GOPATH)

Як я можу це виправити?


5
Весь імпорт є "місцевим" незалежно від шляху імпорту. Детальне пояснення див. У розділі "Як написати код Go" .
JimB

21
@JimB, відкинувши філософські суперечки, мене цікавить, як вирішити згадану вище проблему.
Карлом

3
Я не намагаюся робити філософські висловлювання, я буквально кажу, що всі імпорти відбуваються у вашій локальній файловій системі; ніколи не існує різниці, походять вони з віддаленого репо чи ні. Не намагайтеся використовувати відносні шляхи (вони іноді працюють, але не рекомендуються), і перегляньте документ "Як написати код Go", зокрема розділ "Організація коду" .
JimB

Відповіді:


63

Ну, я зрозумів проблему. В основному Go стартовим шляхом імпорту є$HOME/go/src

Тому мені просто потрібно було додати myappперед назвами пакетів, тобто імпорт повинен бути:

import (
    "log"
    "net/http"
    "myapp/common"
    "myapp/routers"
)

3
використання назви проекту начебто myappпогана ідея, наприклад, якщо ви зміните назву проекту, весь імпорт буде невдалим
TomSawyer

7
Яка альтернатива? Go не рекомендує використовувати відносний імпорт.
Сем Холмс,

11
Звичайно, весь імпорт зазнає невдачі, якщо ви зміните назву проекту. Назва проекту рідко змінюється.
Damien Roche

21
Ну, станом на go1.11 ви можете використовувати нову систему модулів. go mod init <module_name>а потім просто import "<module_name>/<pkg_name>".
крик

Як ми можемо імпортувати github.com/dgrijalva/jwt-go у наш файл .go? Моя папка jwt-go знаходиться всередині src / github.com / dgrijalva
Thakur

30

Якщо ви використовуєте Go 1.5 вище, ви можете спробувати скористатися функцією продажу . Це дозволяє помістити ваш локальний пакет у папку постачальника та імпортувати його з більш коротким шляхом. У вашому випадку ви можете помістити вашу загальну папку та папку з маршрутизаторами всередину папки постачальника, щоб вона була схожою

myapp/
--vendor/
----common/
----routers/
------middleware/
--main.go

і імпортувати його так

import (
    "common"
    "routers"
    "routers/middleware"
)

Це буде працювати, оскільки Go спробує шукати ваш пакет, починаючи з каталогу постачальника вашого проекту (якщо він має хоча б один файл .go) замість $ GOPATH / src.

FYI: Ви можете зробити більше з постачальником, оскільки ця функція дозволяє вам помістити "весь код вашої залежності" для пакету всередину каталогу власного проекту, щоб він міг завжди отримувати однакові версії залежностей для всіх збірок. Це як npm або pip у python, але вам потрібно вручну скопіювати свої залежності до вашого проекту, або якщо ви хочете це зробити просто, спробуйте виглядати говендором Даніелем Теофаном

Щоб дізнатись більше про цю функцію, спробуйте шукати тут

Розуміння та використання папки продавця Даніелем Теофаном

Розуміння управління залежністю Go від Лукаса Фернандеса да Коста

Сподіваюся, вам чи комусь ще це знайдеться корисно


18

Шляхи імпорту відносно вашої $GOPATHта $GOROOTзмінних середовища. Наприклад, з наступним $GOPATH:

GOPATH=/home/me/go

Пакети, що знаходяться в /home/me/go/src/lib/commonта /home/me/go/src/lib/routersімпортуються відповідно як:

import (
    "lib/common"
    "lib/routers"
)

Так, першим прикладом була моя помилка.
wlredeye

Що ви маєте на увазі під відносним шляхом, який не підтримується інструментом?
wlredeye

2
Не можна go installпакувати, що використовує відносний імпорт.
JimB

Думаю, тут його непорозуміння. Я маю на увазі відносно GOPATH. Не просто відносно, як "../../mypackage"
wlredeye

Це стосувалося тієї частини, яку ви виправили щодо імпорту щодо поточного каталогу. Так, усі імпорти користувачів відносно $GOPATH/src.
JimB

5

Місцевий пакет - це неприємна проблема в go.

Для деяких проектів нашої компанії ми вирішили взагалі не використовувати підпакети.

  • $ glide install
  • $ go get
  • $ go install

Всі працюють.

Для деяких проектів ми використовуємо підпакети та імпортуємо локальні пакети з повним шляхом:

import "xxxx.gitlab.xx/xxgroup/xxproject/xxsubpackage

Але якщо ми розгалужимо цей проект, то підпакети все одно посилаються на вихідний.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.