2012-05-21 32 views
32

Làm cách nào để nhập tương đối từ thư mục chính?Nhập tương đối từ thư mục mẹ

Từ meme/cmd/meme:

import "../../../meme" 

này đưa ra một lỗi mơ hồ:

[email protected]:~/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme$ go get bitbucket.org/anacrolix/meme/cmd/meme 

can't load package: /home/matt/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme/main.go:8:2: local import "../../../meme" in non-local package 

[email protected]:~/gopath/src/bitbucket.org/anacrolix/meme/cmd/meme$ echo $GOPATH 

/home/matt/gopath 

Làm thế nào để nhập khẩu tại địa phương từ một thư mục cha?

+0

Tôi đã thử cách này theo một vài cách khác nhau và tôi không thấy lỗi mơ hồ mà bạn đề cập đến. Bạn có nghĩa là bạn đã tìm thấy từ ngữ mơ hồ hoặc văn bản thông báo bao gồm từ mơ hồ. Hai cách tôi đã thử là meme/cmd/meme trong GOPATH, và sau đó là bên ngoài GOPATH. Trong cả hai trường hợp, đường dẫn nhập tương đối hoạt động tốt cho tôi. Bạn có thể cung cấp thêm chi tiết về những gì không hiệu quả với bạn không? – Sonia

+0

@Sonia bạn đã thử với công cụ di chuyển chưa? Tôi sẽ bổ sung thêm chi tiết. –

+0

Có. Tôi loại giả định rằng bạn đã có một gói trong meme và một thực thi trong meme/cmd/meme. Đối với trường hợp GOPATH, hãy chạy hoặc đi cài đặt trên tệp thực thi vừa hoạt động. Đối với trường hợp out-of-GOPATH tôi đã biên soạn gói meme với công cụ go 6g và đi gói công cụ. Việc nhập khẩu trong gói chính sau đó chỉ cần thiết để được ../../meme, để trỏ đến .a nhưng nếu không đi công cụ 6g và đi công cụ 6l xây dựng một thực thi làm việc mà truy cập vào gói. – Sonia

Trả lời

16

Cảm ơn bạn đã thêm câu hỏi của mình. Đầu tiên, một câu trả lời, sau đó một số lời giải thích. Tôi đã xây dựng mã của bạn bằng cách,

  1. để lấy, giống như bạn đã có. (Tôi đã bỏ qua các thông báo lỗi.)
  2. đặt đường nhập trong main.go quay lại "../../../meme", như bạn muốn làm.
  3. (nhận xét một chút mã có chứa biến không sử dụng.)
  4. sau đó trong thư mục meme/cmd/meme, hoặc go run main.go hoặc go build main.go đã hoạt động.

Tôi đã sai trong nhận xét của mình trước đó khi tôi nói đi cài đặt công trình; Tôi nên nói đi xây dựng.

Tuy nhiên, khóa chính là go build không hoạt động; bạn phải nhập go build main.go. Điều này là do lệnh go không cho phép "nhập nội bộ trong các gói không phải cục bộ." Bạn nói đúng rằng đặc điểm kỹ thuật là ít giúp đỡ ở đây. Nó chen lẩy nói rằng, "Cách giải thích của ImportPath phụ thuộc vào việc triển khai thực hiện." Hành vi triển khai hiện tại được đặt bằng CL 5787055, sau đó là debated at length trên Go-nut.

"Địa phương" có nghĩa là được chỉ báo bằng đường dẫn tương đối của hệ thống tệp. Rõ ràng là một con đường tương đối bắt đầu với .. là địa phương, do đó, lừa chỉ là nhận được các go lệnh để điều trị chính như là một gói địa phương là tốt. Nó dường như không làm điều này khi bạn gõ go build, nhưng khi bạn gõ go build main.go.

2

Nhập khẩu relarive được hỗ trợ khi sử dụng trình biên dịch, trình liên kết, ... theo cách thủ công trực tiếp. Công cụ 'go' (build) không hỗ trợ giống nhau (bằng cách nào đó có thể so sánh với ví dụ Java).

+1

Khi có thể. Xin lưu ý rằng đây là một hoạt động không được khuyến khích. – mvrak

41

Chỉnh sửa: Đường dẫn nhập tương đối không phải là cách để thực hiện trong Go. Thiếu tài liệu cho thấy một cái gì đó về sự phổ biến của đường dẫn tương đối, và tôi không thấy một lý do để sử dụng chúng. Tổ chức mã được đề xuất của Go hoạt động khá tốt. Mỗi gói phải có đường dẫn nhập duy nhất và được nhập ở mọi nơi bằng cùng một đường dẫn nhập đó.

Xem cách gói như github.com/ha/doozerd/peerimports its neighbors. Đây là một thực tế phổ biến trong các dự án Go và tôi đã nhìn thấy nó rất nhiều lần. Gói camlistore.org/pkg/auth (cũng trên GitHub; được viết bởi một trong những tác giả chính của Go) nhập camlistore.org/pkg/netutil bằng đường dẫn đầy đủ.

Thậm chí nếu bạn đang có cả lệnh và thư viện trong cùng một dự án thì phương pháp này hoạt động. Trong các câu hỏi ban đầu của bạn, bạn đã yêu cầu một cách khôn ngoan các phương pháp hay nhất. Tôi đã cố hết sức để giải thích các phương pháp hay nhất về vấn đề này.


Đường dẫn nhập không thể tương đối trong Go. Tôi khuyên bạn nên đọc How to Write Go Code, bài đọc cần thiết về tổ chức các dự án Go. Dưới đây là tổng quan ngắn:

Tạo một thư mục như ~/go để phát triển Go của bạn. Sau đó nói:

$ export GOPATH=~/go 
$ mkdir $GOPATH/{src,bin,pkg} 

$GOPATH/src giữ mã nguồn cho tất cả các gói Go của bạn, ngay cả những người tải về của bạn với go get. binpkg giữ đầu ra của bộ sưu tập. Các gói có tên gói main là các lệnh và năng suất cho các tệp nhị phân có thể thực thi, truy cập vào $GOPATH/bin. Các gói khác là các thư viện và các tệp đối tượng được biên dịch của chúng được đặt trong $GOPATH/pkg.

Bây giờ, nếu bạn đặt mã của mình trong $GOPATH/src/matt/meme, bạn có thể nhập mã đó theo import "matt/meme". Bạn nên sử dụng tiền tố cho tên gói của mình và để tên gói ngắn cho thư viện chuẩn. Đó là lý do tại sao tôi đã sử dụng $GOPATH/src/matt/meme thay vì $GOPATH/src/meme.

Sắp xếp mã của bạn xung quanh ý tưởng này.

+1

Tôi tin rằng họ có thể Mostafa, nhưng nó không có giấy tờ. –

+0

@MattJoiner Bạn nói đúng. Tôi không biết họ có thể sử dụng công cụ Go. Nhưng dù sao tôi không nghĩ chúng ta nên sử dụng chúng. Phải cập nhật câu trả lời của tôi. – Mostafa

+11

Đường dẫn tương đối phù hợp cho trường hợp sử dụng một (IMO quan trọng): xử lý các kho lưu trữ chia đôi. Nếu bạn nĩa repo của ai đó trên github, bạn sẽ phải cập nhật tất cả các câu lệnh import để tham khảo bản sao của bạn, và sau đó nhớ không đẩy những thứ đó lên trên (hoặc mong rằng thượng nguồn sẽ loại trừ chúng trong quá trình hợp nhất). Chỉ trở nên cẩu thả. –

Các vấn đề liên quan