Cách tắt lỗi nhập không sử dụng Golang


96

Theo mặc định, Go coi nhập không sử dụng là lỗi, buộc bạn phải xóa nhập. Tôi muốn biết liệu có tồn tại một số hy vọng để thay đổi hành vi này, ví dụ: giảm nó thành cảnh báo.

Tôi thấy vấn đề này cực kỳ khó chịu, ngăn cản tôi thích viết mã trong cờ vây.

Ví dụ: tôi đang thử nghiệm một số mã, vô hiệu hóa một phân đoạn / chức năng. Một số chức năng từ lib không còn được sử dụng (ví dụ: fmt, lỗi, bất cứ điều gì), nhưng tôi sẽ cần phải kích hoạt lại chức năng sau khi kiểm tra một chút. Bây giờ chương trình sẽ không biên dịch trừ khi tôi xóa những lần nhập đó và vài phút sau, tôi cần nhập lại lib.

Tôi đã thực hiện lại quá trình này khi phát triển một chương trình GAE.


1
Không phải là một ý kiến ​​hay nếu để các nhập chưa sử dụng trong mã của bạn, nhưng bạn có thể tạm thời nhận xét chúng.
elithrar

70
Tôi đồng ý rằng không phải là một ý kiến ​​hay nếu để lại những phần nhập không sử dụng nhưng sẽ là một ý tưởng tồi nếu lãng phí nỗ lực của lập trình viên để làm những việc như thế này một cách không cần thiết, đặc biệt là điều này xảy ra rất thường xuyên khi thử nghiệm một thứ gì đó. Những phiếu bầu đó phải là vì thái độ của tôi đối với GO của những người hâm mộ cờ vây đó.
Nick

6
Đó là một tính năng, không phải một lỗi .
beatgammit.

1
Loại bỏ hàng nhập khẩu không sử dụng là một điều tốt. Có nhiều hướng dẫn kiểu yêu cầu tất cả các cảnh báo phải được coi là lỗi, vì vậy việc thêm một cảnh báo mới nói chung là một ý tưởng tồi. Có lẽ cờ -dev có thể là một thỏa hiệp có thể xảy ra, nhưng var _ = <module>.Functionhoạt động tốt và nó đủ dễ thấy để ngăn nó trở thành một thực tế phổ biến.
deft_code

1
Khi ai đó đang chạm vào trong các câu trả lời bên dưới, tôi khuyên bạn nên sử dụng IDE quản lý việc nhập (Gogland, LiteIDE, v.v. - có một số) hoặc có goimportsnhư một bước trong quy trình xây dựng của bạn. Không có một trong hai thứ đó, nó sẽ già đi rất nhanh.
Josef Grahn

Câu trả lời:


36

Thêm dấu gạch dưới ( _) trước tên gói sẽ bỏ qua lỗi nhập không sử dụng.

Đây là một ví dụ về cách bạn có thể sử dụng nó:

import (
    "log"
    "database/sql"

    _ "github.com/go-sql-driver/mysql"
)

Để chỉ nhập một gói cho các tác dụng phụ của nó (khởi tạo), hãy sử dụng số nhận dạng trống làm tên gói rõ ràng.

Xem thêm tại https://golang.org/ref/spec#Import_decl Tuyên


Đây là câu trả lời chính xác. Dựa trên Tài liệu đặc tả của GoLang, nó được sử dụng để nhập một gói chỉ cho các tác dụng phụ (khởi tạo). GoLang Spec Doc tại đây: golang.org/ref/spec#Import_decl Tuyên
Sẽ vào

Đơn giản là tuyệt vời. Điều này nên nằm trong danh sách mười điều hàng đầu mà các nhà phát triển mới làm quen với golang nên biết. Cảm ơn bạn!
JM Janzen

9
Không hữu ích lắm. Vấn đề với điều này là nếu sau này bạn muốn sử dụng lại việc nhập, bạn phải xóa _(nếu không, gói không thể được tham chiếu vì nó không có tên). Nếu bạn định làm điều đó, bạn cũng có thể chỉ cần nhận xét / bỏ ghi chú nó. Thủ var _ = ...thuật không có vấn đề này.
EM0

Nếu bạn thêm dấu gạch chân để "fmt"trong Gogland, nó sẽ tự động thêm "fmt"để bạn có cả hai _"fmt""fmt", mà làm cho nó vô dụng trong IDE này
kramer65

26

Thủ var _ = fmt.Printfthuật rất hữu ích ở đây.


Tôi thích giải pháp này. Nó đủ xấu để làm cho nó không mong muốn, nhưng nó hoạt động để nó ở đó nếu bạn thực sự cần nó.
deft_code

3
Để biết thêm chi tiết, vui lòng kiểm tra liên kết này tip.golang.org/doc/effective_go.html#blank_unused
Deepak Singh Rawat

3
Nó hữu ích trong thời điểm này, nhưng khi tôi sử dụng kỹ thuật này, tôi có xu hướng không quay lại và xóa số nhận dạng trống không sử dụng sau đó, khiến các mục nhập sẽ tồn tại khi tôi thực sự không có ý định sử dụng chúng về lâu dài. Sử dụng một công cụ như goimports đã giải quyết được vấn đề thực sự và đảm bảo rằng hàng nhập khẩu của tôi luôn ở mức tối thiểu và sạch sẽ.
mdwhatcott

Theo tôi vẫn là một vụ hack ngu ngốc, mặc dù có lẽ là cách hiệu quả nhất để làm.
Anthony

+1 vì điều này có thể được thực hiện ở bất kỳ đâu trong tệp , điều này thường là một ý tưởng tồi tệ nhưng thực sự hữu ích để giúp bạn tiết kiệm khỏi việc phải di chuyển xung quanh tệp để đến importcâu lệnh và quay lại khi bạn chỉ đang cố gắng biên dịch hoặc kiểm tra một số tệp mã mà bạn đang lặp đi lặp lại .
mtraceur

21

Tôi có cùng một vấn đề. Tôi hiểu lý do tại sao họ triển khai ngôn ngữ để không cho phép nhập và biến không sử dụng, nhưng cá nhân tôi thấy tính năng này gây phiền nhiễu khi viết mã của tôi. Để giải quyết vấn đề này, tôi đã thay đổi xung quanh trình biên dịch của mình để cho phép các cờ tùy chọn cho phép các biến và nhập không sử dụng trong mã của tôi.

Nếu quan tâm, bạn có thể xem tại https://github.com/dtnewman/modified_golang_compiler .

Bây giờ, tôi có thể chỉ cần chạy mã bằng một lệnh, chẳng hạn như go run -gcflags '-unused_pkgs' test.go và nó sẽ không gây ra những lỗi "nhập không sử dụng" này. Nếu tôi bỏ qua những cờ này, thì nó sẽ trở về mặc định không cho phép nhập không sử dụng.

Thực hiện điều này chỉ yêu cầu một số thay đổi đơn giản. Những người theo chủ nghĩa thuần túy Go có thể sẽ không hài lòng với những thay đổi này vì có lý do chính đáng để không cho phép các biến / nhập không được sử dụng, nhưng cá nhân tôi đồng ý với bạn rằng vấn đề này khiến việc viết mã trong Go kém thú vị hơn nhiều, đó là lý do tại sao tôi thực hiện những thay đổi này đối với trình biên dịch.


2
Tôi cũng đã thực hiện tương tự với bản phát hành 1.6, hãy kiểm tra tại đây nếu quan tâm: github.com/ronelliott/go/tree/release-branch.go1.6 LƯU Ý: một số thử nghiệm sẽ không thành công
Ron E

2
Tôi thích ý tưởng đằng sau điều này. Tôi thấy rằng bạn vẫn đang fork ở phiên bản 1.2, điều này khiến nó trở nên vô dụng. Điều này nên được bao gồm trong trình biên dịch go tiêu chuẩn, ít nhất để go run main.govô hiệu hóa các lỗi theo mặc định, trong khi bật go buildcác lỗi. Bằng cách đó, dễ dàng phát triển bằng cách sử dụng go runvà khi đã đến lúc xây dựng để sản xuất, bạn vẫn buộc phải dọn dẹp mã của mình.
kramer65

17

Sử dụng goimports . Về cơ bản, nó là một nhánh của gofmt, được viết bởi Brad Fitzpatrick và bây giờ được bao gồm trong các gói công cụ cờ vây. Bạn có thể định cấu hình trình chỉnh sửa của mình để chạy nó bất cứ khi nào bạn lưu tệp. Bạn sẽ không bao giờ phải lo lắng về vấn đề này nữa.


5

Nếu bạn đang sử dụng fmtgói để in chung ra bảng điều khiển trong khi phát triển và thử nghiệm thì bạn có thể tìm thấy giải pháp tốt hơn trong gói nhật ký .


5
Hoặc chức năng nội trang printlnmà mọi người dường như luôn quên.
MatrixFrog

2
@MatrixFrog Về lâu dài, không phải là ý kiến ​​hay nếu bạn xây dựng dựa trên các chức năng này vì chúng có thể biến mất theo thời gian. Sử dụng nhật ký là một ý tưởng hay vì bạn có thể giữ những thứ này và nó là một phần của thư viện chuẩn và khó có thể bị xóa. Xem thông số kỹ thuật để biết chi tiết.
nemo

1
Nội trang println?? Tin mới đối với tôi. Nó không có giấy tờ? Tôi không thể tìm thấy nó ở bất cứ đâu.
Matt

1
@nemo điểm tốt. Chúng hoàn hảo khi bạn cần in thứ gì đó ra giấy nhanh chóng, nhưng bạn không có ý định thực sự kiểm tra nó. Có thể không tốt khi sử dụng chúng trong bất kỳ trường hợp nào khác.
MatrixFrog

1
@MartinTournoij - Tôi không đồng ý. Đây là giải pháp cuối cùng tôi đã tìm thấy khi tôi gặp vấn đề này 5 năm trước và với hơn 5 lượt ủng hộ, nó rõ ràng đã giúp ích cho những người khác. Tôi là một người mới sử dụng fmtgói để ghi nhật ký, không biết rằng có một gói ghi nhật ký được tạo sẵn.
OldCurmudgeon,

5

Sử dụng if false { ... }để bình luận một số mã. Mã bên trong dấu ngoặc nhọn phải đúng về mặt cú pháp, nhưng có thể là mã vô nghĩa nếu không.


3
Hơn đúng cú pháp, bất kỳ biến tham chiếu (ví dụ foo.Bar) phải tồn tại vv
Rồng

Đây không phải là rất sạch sẽ hoặc thành ngữ. Có một lý do tại sao Go được thiết kế cách thức mà nó là
Acidic9

1
Đây là một kỹ thuật hay khi một người chỉ đơn giản là thử mọi thứ trong khi phát triển một tập lệnh hoặc khám phá các API trong Golang. Cảm ơn topkip!
Jay Taylor,

2

Rất nhiều người đã bình luận với lý do xác đáng và tôi cũng thừa nhận ý định ban đầu của tác giả. Tuy nhiên, Rob Pike đã đề cập trong các diễn đàn khác nhau rằng cờ vây là kết quả của việc đơn giản hóa các quy trình mà một số ngôn ngữ lập trình chính thống khác thiếu hoặc không dễ đạt được. Đó là ngữ nghĩa ngôn ngữ của Go cũng như để làm cho việc biên dịch nhanh hơn, có rất nhiều thứ được áp dụng mà ban đầu có vẻ không hiệu quả.

Nói một cách ngắn gọn, các lần nhập không sử dụng được coi là lỗi trong Go vì nó làm mờ chương trình và làm chậm quá trình biên dịch. Sử dụng nhập cho tác dụng phụ (_) là một cách giải quyết, tuy nhiên, tôi thấy điều này đôi khi khó hiểu khi có sự kết hợp của các mục nhập hợp lệ với các tác dụng phụ cùng với các tác dụng phụ được nhập hoàn toàn cho mục đích gỡ lỗi / thử nghiệm, đặc biệt là khi cơ sở mã là lớn và có khả năng quên và không xóa do vô ý có thể gây nhầm lẫn cho các kỹ sư / người đánh giá khác sau này. Tôi đã từng nhận xét về những cái không sử dụng, tuy nhiên, các IDE phổ biến như mã VS và Goland có thể sử dụng goimportsdễ dàng, điều này thực hiện khá tốt việc chèn và xóa các nhập. Vui lòng tham khảo liên kết để biết thêm thông tin, https://golang.org/doc/effective_go.html#blank_import


Cảm ơn vì điều đó! Tôi khuyên bạn nên sao chép và dán dòng mã một cách rõ ràng từ URL bạn đã đăng vào phản hồi của mình như một ví dụ cụ thể về việc nhập để có tác dụng phụ: import _ "net/http/pprof"
Dragon

1
Cảm ơn @Dragon cho đề xuất của bạn! Vì tôi là một cộng tác viên mới, với sự giúp đỡ của những người như bạn, tôi sẽ nhanh chóng trở nên tốt hơn với các bài đăng của mình.
sbcharr

-1

đặt cái này lên đầu tài liệu của bạn và quên đi những lần nhập chưa sử dụng:

import (
    "bufio"
    "fmt"
    "os"
    "path/filepath"
)

var _, _, _, _ = fmt.Println, bufio.NewReader, os.Open, filepath.IsAbs

1
Thay vì làm cho trình biên dịch tạo ra mã chết nếu bạn thực sự muốn làm điều này, hãy sử dụng _các biến toàn cục để thay thế (ví dụ: một gói trên mỗi dòng hoặc nếu bạn nhấn mạnh, tất cả cùng nhau như var _, _, _, _ = fmt.Println, bufio.NewReader, os.Open, filepath.IsAbs:). Nhưng đừng làm điều này, chỉ sử dụng goimports.
Dave C
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.