2013-04-23 34 views
34

Tôi đang làm việc trên dự án Go trong một tháng. Điều tốt là Go thực sự hiệu quả cao. Nhưng sau một tháng phát triển, tôi đã có hàng nghìn dòng mã và nhiều mã số packages. Để tránh chu kỳ nhập khẩu là một vấn đề lớn đối với tôi rằng bất cứ lúc nào tôi nhận được một lỗi chu kỳ nhập khẩu, tôi không có ý tưởng nơi mà vấn đề có thể được ở lần đầu tiên.Bất kỳ lời khuyên nào tốt về cách tránh chu kỳ nhập trong Go?

Trình biên dịch Go cũng chỉ có thông báo rất đơn giản mà luôn không đủ tốt để xác định sự cố nhanh chóng như: main.go:7:3: import cycle not allowed. Nó sẽ chỉ giúp bạn biết tệp nào có thể gây ra sự cố nhưng không có gì sâu sắc hơn. Vì mối quan hệ import ngày càng trở nên phức tạp hơn trong khi mã tăng lên, tôi mong muốn biết cách tránh chu kỳ nhập hiệu quả hơn trong Go. Bất kỳ sự giúp đỡ nào cũng được đánh giá cao.

Trả lời

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

Sẽ hiển thị phụ thuộc nhập khẩu đối với gói tại <import-path> - hoặc trong thư mục hiện hành nếu <import-path> được bỏ trống. Ngoài ra,

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

hy vọng sẽ hiển thị một số thông tin hữu ích trong trường hợp của bạn. Xem thêm đầu ra của

go help list 

để biết thêm thông tin về công cụ danh sách go.

+11

+1 để đến 10K! – peterSO

+2

@peterSO: Cảm ơn bạn ;-) – zzzz

+2

Chắc chắn tốt để biết, thậm chí không biết về danh sách đi, thực sự. – mna

36

Để bổ sung cho câu trả lời của jnml (giúp "gỡ rối" các tham chiếu vòng tròn), bạn có thể sử dụng dependency inversion để ngắt các chu kỳ đó, cùng với tiêm phụ thuộc. Đối với một ứng dụng, tôi luôn cố gắng làm theo các hướng dẫn của Clean Architecture - xem here cho ví dụ cụ thể về Go - và tôi thấy rằng "triển khai không khai báo" của Giao diện (nghĩa là, bạn không phải nói rõ ràng type MyStruct struct implements IfceSomething) làm cho điều này rất đơn giản. Vì vậy, nếu bạn có gói A -> B -> C -> A, bạn tạo InterfaceA (một số tên liên quan, rõ ràng, liên quan đến hành vi hơn gói liên quan :) trong gói C và làm cho nó phụ thuộc vào giao diện này thay vì trên gói A, và bạn đảm bảo gói A "triển khai" giao diện này. Sau đó, bạn chỉ cần cung cấp triển khai cụ thể A đến C tại một số điểm (nhiều khả năng ở đây, tôi thường làm điều này "keo" mã trong gói chính mà biết về tất cả các phụ thuộc).

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