2013-04-23 14 views
34

Pracuję nad projektem Go przez miesiąc. Dobrą rzeczą jest to, że Go jest bardzo wydajny. Ale po miesiącu rozwoju mam już tysiące linii kodu i wiele packages. Aby uniknąć cyklu importowania, jest dla mnie poważnym problemem, że w każdym momencie, gdy dostaję błąd cyklu importu, nie mam pojęcia, gdzie może być problem po raz pierwszy.Jakiejkolwiek porady na temat unikania cyklu importu w Go?

Kompilator Go ma również bardzo proste powiadomienie, które nie zawsze jest na tyle dobre, aby szybko zlokalizować problem, na przykład: main.go:7:3: import cycle not allowed. Pomoże Ci tylko dowiedzieć się, który plik może powodować problem, ale nie ma nic głębszego. Ponieważ relacje stają się coraz bardziej złożone, a kod rośnie, bardzo chciałbym wiedzieć, jak efektywniej unikać cyklu importowania w Go. Każda pomoc jest doceniana.

Odpowiedz

54
go list -f '{{join .Deps "\n"}}' <import-path> 

Pokaże zależności przywozowych na opakowaniu w <import-path> - czy w bieżącym katalogu, jeśli <import-path> pozostaje pusta. Alternatywnie

go list -f '{{join .DepsErrors "\n"}}' <import-path> 

Mam nadzieję, że pokaże kilka przydatnych informacji w Twojej sprawie. Dodatkowe informacje o narzędziu do przeglądania listy znajdują się również w danych wyjściowych urządzenia

go help list 

+11

+1, aby dostać się do 10K! – peterSO

+2

@peterSO: Dziękuję ;-) – zzzz

+2

Zdecydowanie dobrze wiedzieć, nie wiedziałem nawet o liście go. – mna

36

Aby uzupełnić odpowiedź jnml (która pomaga w "debugowaniu" problemów z odniesieniami kołowymi), można użyć dependency inversion, aby przerwać te cykle, w połączeniu z wtryskiem zależności. W przypadku aplikacji zawsze staram się postępować zgodnie z wytycznymi Clean Architecture - patrz here dla przykładu specyficznego dla Go - i uważam, że Go "nie deklaratywna implementacja" interfejsów (to znaczy, że nie musisz jednoznacznie powiedzieć: type MyStruct struct implements IfceSomething) sprawia, że ​​jest to bardzo proste.

Tak więc, jeśli masz pakiety A -> B -> C -> A, tworzymy InterfaceA (pewna istotna nazwa, oczywiście, więcej związanych z zachowaniem niż związanych z pakietem :) w pakiecie C i zależy od tego interfejsu, a nie od pakietu A, a ty upewnij się, że pakiet A "implementuje" ten interfejs.

W tym momencie wystarczy podać konkretną implementację od A do C (wiele możliwości tutaj, zwykle robię ten "klejący" kod w głównym pakiecie, który wie o wszystkich zależnościach).

Powiązane problemy