Làm thế nào để nhập các gói cục bộ đang di chuyển?


90

Tôi mới bắt đầu làm việc trên một mã ví dụ mà tôi muốn bản địa hóa.

Trong main.gocâu lệnh nhập ban đầu, nó là:

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

Bây giờ tôi có commonroutersđóng gói trong/home/me/go/src/myapp

Vì vậy, tôi đã chuyển đổi câu lệnh nhập thành:

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

Nhưng khi chạy go install myapptôi gặp những lỗi sau:

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

Ngoài ra, khi tôi sử dụng commonroutersthay vì ./common./routerstrong câu lệnh nhập, tôi nhận được:

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)

Làm thế nào tôi có thể sửa lỗi này?


5
Tất cả hàng nhập khẩu là "địa phương" bất kể đường dẫn nhập khẩu. Xem "Cách viết mã cờ vây" để được giải thích chi tiết.
JimB

21
@JimB gạt những tranh luận triết học sang một bên, điều tôi quan tâm là cách giải quyết vấn đề nêu trên.
Karlom

3
Tôi không cố gắng đưa ra một tuyên bố triết học, tôi thực sự đang nói rằng tất cả các lần nhập đều xảy ra trong hệ thống tệp cục bộ của bạn; không bao giờ có bất kỳ sự khác biệt nào cho dù chúng có nguồn gốc từ một repo từ xa hay không. Đừng cố gắng sử dụng các đường dẫn tương đối (đôi khi chúng hoạt động, nhưng không được khuyến khích) và xem qua tài liệu "Cách viết mã đi", cụ thể là phần về "Tổ chức mã" .
JimB

Câu trả lời:


64

Vâng, tôi đã tìm ra vấn đề. Về cơ bản, con đường bắt đầu để nhập là$HOME/go/src

Vì vậy, tôi chỉ cần thêm myappvào trước tên gói, tức là, nhập phải là:

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

3
sử dụng tên dự án như myapplà một ý tưởng tồi, chẳng hạn như nếu bạn thay đổi tên dự án, tất cả quá trình nhập sẽ không thành công
TomSawyer

7
Giải pháp thay thế là gì? Go không khuyên bạn nên sử dụng nhập khẩu tương đối.
Sam Holmes

11
Tất nhiên tất cả các lần nhập sẽ không thành công nếu bạn thay đổi tên dự án. Tên dự án hiếm khi thay đổi.
Damien Roche

21
Vâng, kể từ go1.11, bạn có thể sử dụng hệ thống mô-đun mới. go mod init <module_name>và sau đó chỉ import "<module_name>/<pkg_name>".
shrek

Làm cách nào chúng ta có thể nhập github.com/dgrijalva/jwt-go trong tệp .go của mình? Thư mục jwt-go của tôi nằm bên trong src / github.com / dgrijalva
Manik Thakur

30

Nếu bạn đang sử dụng Go 1.5 ở trên, bạn có thể thử sử dụng vendoring tính năng. Nó cho phép bạn đặt gói cục bộ của mình trong thư mục nhà cung cấp và nhập nó với đường dẫn ngắn hơn. Trong trường hợp của bạn, bạn có thể đặt thư mục chungbộ định tuyến của mình bên trong thư mục nhà cung cấp để nó giống như

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

và nhập nó như thế này

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

Điều này sẽ hiệu quả vì Go sẽ cố gắng tra cứu gói của bạn bắt đầu từ thư mục nhà cung cấp dự án của bạn (nếu nó có ít nhất một tệp .go) thay vì $ GOPATH / src.

FYI: Bạn có thể làm được nhiều việc hơn với nhà cung cấp, vì tính năng này cho phép bạn đặt "tất cả mã phụ thuộc của bạn" cho một gói bên trong thư mục dự án của riêng bạn để nó luôn có thể nhận được các phiên bản phụ thuộc giống nhau cho tất cả các bản dựng. Nó giống như npm hoặc pip trong python, nhưng bạn cần sao chép thủ công các phụ thuộc của mình vào dự án của bạn hoặc nếu bạn muốn làm cho nó dễ dàng, hãy thử xem govendor của Daniel Theophanes

Để tìm hiểu thêm về tính năng này, hãy thử tra cứu tại đây

Hiểu và Sử dụng Thư mục Nhà cung cấp của Daniel Theophanes

Hiểu về quản lý phụ thuộc vào Go của Lucas Fernandes da Costa

Tôi hy vọng bạn hoặc ai đó tìm thấy nó một cách hữu ích


18

Đường dẫn nhập có liên quan đến các biến môi trường $GOPATHvà của bạn $GOROOT. Ví dụ, với những điều sau $GOPATH:

GOPATH=/home/me/go

Các gói nằm trong /home/me/go/src/lib/common/home/me/go/src/lib/routersđược nhập tương ứng như:

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

Vâng, ví dụ đầu tiên là sai lầm của tôi.
wlredeye

Ý bạn là gì khi đường dẫn tương đối không được công cụ hỗ trợ?
wlredeye

2
Bạn không thể go installgói sử dụng nhập tương đối.
JimB

Tôi nghĩ rằng sự hiểu lầm của nó ở đây. Ý tôi là liên quan đến GOPATH. Không chỉ tương đối như "../../mypackage"
wlredeye

Đó là liên quan đến phần bạn đã sửa về việc nhập liên quan đến thư mục hiện tại. Có, tất cả các nhập của người dùng là tương đối với $GOPATH/src.
JimB

5

Gói cục bộ là một vấn đề khó chịu khi di chuyển.

Đối với một số dự án của công ty chúng tôi, chúng tôi quyết định không sử dụng các gói phụ.

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

Tất cả công việc.

Đối với một số dự án, chúng tôi sử dụng các gói phụ và nhập các gói cục bộ với đường dẫn đầy đủ:

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

Nhưng nếu chúng ta phân nhánh dự án này, thì các gói con vẫn là gói ban đầu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.