2012-05-21 20 views
32

Jak wykonać import względny z katalogu nadrzędnego?Względny import z katalogu nadrzędnego

Od meme/cmd/meme:

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

To daje niejednoznaczne błąd:

[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 

Jak importować lokalnie z katalogu nadrzędnego?

+0

Próbowałem tego na kilka różnych sposobów i nie widziałem niejednoznacznego błędu, o którym wspomniałeś. Czy masz na myśli, że znalazłeś niejednoznaczne sformułowanie lub że tekst wiadomości zawierał niejednoznaczne słowo. Dwa sposoby, które wypróbowałem to meme/cmd/meme w GOPATH, a następnie poza GOPATH. W obu przypadkach względna ścieżka importu działała dobrze dla mnie. Czy możesz podać więcej szczegółów na temat tego, co nie działa dla ciebie? – Sonia

+0

@Sonia wypróbowałeś za pomocą narzędzia go? Dodam więcej szczegółów. –

+0

Tak. W pewnym sensie założyłem, że masz paczkę w memu i plik wykonywalny w meme/cmd/meme. W przypadku GOPATH uruchom lub zainstaluj plik wykonywalny, który właśnie działał. Dla przypadku poza GOPATH skompilowałem pakiet memów za pomocą narzędzia go 6g i uruchom pakiet narzędzi. Import w głównym pakiecie musiał po prostu być ../../meme, wskazać na .a ale w przeciwnym razie przejdź do narzędzia 6g i idź do narzędzia 6l zbuduj działający plik wykonywalny, który uzyskał dostęp do pakietu. – Sonia

Odpowiedz

16

Dzięki za dodanie do Twojego pytania. Najpierw odpowiedź, a potem wyjaśnienie. Zrobiłem twój kod,

  1. idź, tak jak to zrobiłeś. (Zignorowałem komunikaty o błędach.)
  2. ustawiając wiersz importu w main.go z powrotem na "../../../meme", tak jak chciałeś.
  3. (zakomentowanie trochę kodu zawierającego nieużywany zmiennej.)
  4. następnie w katalogu mem/CMD/meme albo go run main.go lub go build main.go działa.

Myliłem się w moim komentarzu wcześniej, kiedy powiedziałem, aby zainstalować instalacje; Powinienem był powiedzieć: buduj.

Kluczem jest jednak to, że sam go build nie działa; należy wpisać go build main.go. Wynika to z tego, że polecenie go nie zezwala na "lokalne importowanie w pakietach nielokalnych". Masz rację, że specyfikacja jest tu mało przydatna. Łamie się mówiąc: "Interpretacja ImportPath zależy od implementacji." Bieżące zachowanie implementacji zostało ustawione na CL 5787055, a następnie na debated at length w systemie Go-nuts.

"Lokalny" oznacza wskazywany przez względną ścieżkę systemu plików. Oczywiście ścieżka względna zaczynająca się od .. jest lokalna, więc po prostu otrzymujemy komendę go, aby traktować główny jako pakiet lokalny. Najwyraźniej nie robi się tego po wpisaniu go build, ale robi to po wpisaniu go build main.go.

2

Relacyjne importowanie jest obsługiwane przy ręcznym użyciu kompilatora, linkera, ... bezpośrednio. Narzędzie "go" (kompilacja) nie obsługuje tego samego (w jakiś sposób porównywalne do np. Java).

+1

O ile to możliwe. Proszę wspomnieć, że jest to działanie zniechęcające. – mvrak

41

Edycja: Ścieżki względnego importu nie są sposobem na przejście w Go. Brak dokumentacji pokazuje coś na temat popularności ścieżek względnych i nie widzę powodu, aby z nich korzystać. Jego zalecana organizacja kodu działa całkiem nieźle. Każdy pakiet powinien mieć unikalną ścieżkę importu i być importowany wszędzie pod numerem przy użyciu tej samej ścieżki importu.

Zobacz, jak pakiet taki jak github.com/ha/doozerd/peerimports its neighbors. Jest to powszechna praktyka wśród projektów Go i widziałem to już wiele razy. Pakiet camlistore.org/pkg/auth (również na GitHub; napisany przez jednego z głównych autorów Go) importuje camlistore.org/pkg/netutil pełną ścieżką.

Nawet jeśli masz zarówno polecenia, jak i biblioteki w tym samym projekcie, to podejście działa. W swoich pierwotnych pytaniach mądrze prosiłeś o najlepsze praktyki. Zrobiłem co w mojej mocy, aby wyjaśnić najlepsze praktyki w tej sprawie.


Ścieżki importu nie mogą być względne w ruchu. Polecam lekturę How to Write Go Code, niezbędnej lektury dotyczącej organizowania projektów Go. Oto krótki przegląd:

Utwórz katalog taki jak ~/go dla swojego rozwoju Go. Wtedy mówią:

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

$GOPATH/src posiada kod źródłowy dla wszystkich pakietów odejść, nawet te, pobieranie z go get. bin i pkg zachowaj dane wyjściowe kompilacji. Pakiety o nazwie pakietu main są komendami i dają pliki wykonywalne, które przechodzą na $GOPATH/bin. Inne pakiety to biblioteki, a ich skompilowane pliki obiektów są umieszczane w $GOPATH/pkg.

Teraz, jeśli umieścisz swój kod w $GOPATH/src/matt/meme, możesz go zaimportować przez import "matt/meme". Zaleca się użycie prefiksu dla nazw pakietów i pozostawienie krótkich nazw pakietów dla standardowych bibliotek. Dlatego użyłem $GOPATH/src/matt/meme zamiast $GOPATH/src/meme.

Uporządkuj swój kod wokół tego pomysłu.

+1

Wierzę, że mogą Mostafa, ale jest to nieudokumentowane. –

+0

@MattJoiner Masz rację. Nie wiedziałem, że są one możliwe dzięki narzędziu Go. Ale w każdym razie nie sądzę, że powinniśmy ich używać. Muszę zaktualizować moją odpowiedź. – Mostafa

+11

Ścieżki względne są dobre dla jednego przypadku użycia (krytyczne dla IMO): radzenie sobie z rozproszonymi repozytoriami. Jeśli rozwiniesz czyjś repo na githubie, będziesz musiał zaktualizować wszystkie instrukcje importu, aby odnieść się do twojej kopii, a następnie pamiętaj, aby nie popychać tych w górę (lub oczekiwać, że upstream wykluczy je z fuzji). Po prostu robi się zaniedbany. –

Powiązane problemy