Cách tránh lỗi khó chịu đã khai báo và không được sử dụng


238

Tôi đang học Go nhưng tôi cảm thấy hơi khó chịu khi biên dịch, tôi không nên để bất kỳ biến hoặc gói nào không được sử dụng.

Điều này thực sự khá chậm làm tôi chậm lại. Ví dụ, tôi chỉ muốn khai báo một gói mới và dự định sử dụng nó sau hoặc chỉ cần bỏ qua một số lệnh để kiểm tra. Tôi luôn nhận được lỗi và cần phải bình luận tất cả những sử dụng đó.

Có cách nào để tránh loại kiểm tra này trong Go không?


1
Bạn cũng có thể sử dụng goimports ( godoc.org/code.google.com/p/go.tools/cmd/goimports ) để tự động thêm / xóa nhập khẩu cho bạn.
elithrar


3
Tôi vẫn cảm thấy một tùy chọn trình biên dịch sẽ hữu ích cho quy trình "Tôi muốn bình luận một cái gì đó để hỗ trợ gỡ lỗi".
RJFalconer

13
Tính năng này là một cách tuyệt vời để lãng phí thời gian của mọi người lol, vấn đề là gì? Khi bạn cam kết / gửi mã, ok không có vars không sử dụng là tốt, nhưng khi phát triển nó? Kinh khủng.
Alexander Mills

Đó là năm 2020 và tôi không thể tin rằng họ vẫn chưa sửa lỗi này (ngay cả với cờ biên dịch). Tôi đã thực hiện một dự án trong Go khoảng 5 năm trước và nói chung là thích ngôn ngữ này nhưng nó không thể sử dụng được cho tôi chỉ vì điều này. Cách tôi mã hóa tôi liên tục bình luận / không chú ý đến công cụ, vì vậy "tính năng" này trong Go khiến mọi thứ mất gấp đôi thời gian của tôi ... Tôi đã kiểm tra lại sau mỗi vài tháng để xem liệu cảm giác về lý trí đã vượt qua nhóm Go, và cho đến nay không có may mắn ... Sucks. Đó là một ngôn ngữ tuyệt vời khác và tôi thích sử dụng nó hơn, nhưng hiện tại nó không thể sử dụng được cho tôi.
Ruslan

Câu trả lời:


235

Lỗi đó là ở đây để buộc bạn viết mã tốt hơn và chắc chắn sử dụng mọi thứ bạn khai báo hoặc nhập. Nó giúp việc đọc mã được viết bởi người khác dễ dàng hơn (bạn luôn chắc chắn rằng tất cả các biến được khai báo sẽ được sử dụng) và tránh một số mã chết có thể xảy ra.

Nhưng, nếu bạn thực sự muốn bỏ qua lỗi này, bạn có thể sử dụng mã định danh trống ( _):

package main

import (
    "fmt" // imported and not used: "fmt"
)

func main() {
    i := 1 // i declared and not used
}

trở thành

package main

import (
    _ "fmt" // no more error
)

func main() {
    i := 1 // no more error
    _ = i
}

Như đã nói bởi kostix trong các bình luận bên dưới, bạn có thể tìm thấy vị trí chính thức của nhóm Go trong Câu hỏi thường gặp :

Sự hiện diện của một biến không được sử dụng có thể chỉ ra một lỗi, trong khi nhập không sử dụng chỉ làm chậm quá trình biên dịch. Tích lũy đủ nhập khẩu không sử dụng trong cây mã của bạn và mọi thứ có thể trở nên rất chậm. Vì những lý do này, Go không cho phép.


90
Tuy nhiên, điều này không quá khác biệt so với việc bình luận. Và, tôi hiểu rằng đây là mã tốt hơn nhưng sẽ tốt hơn nếu chúng ta có thể đóng một kiểm tra tại sao kiểm tra mã của chúng tôi và sau đó mở lại kiểm tra này sau khi chúng tôi muốn hoàn thành mã và làm cho nó sạch?
A-letubby

21
@kostix Chà .. nó có thể không làm bạn chậm lại vì bạn có thể là một chuyên gia nhưng nó là cho tôi và cách tôi viết mã. Tôi chỉ tự hỏi nếu có cách tốt hơn. Nhưng dù sao, cảm ơn cho Câu hỏi thường gặp! Bằng cách đọc này, tôi hoàn toàn có thể hiểu lý do tại sao golang làm theo cách này.
A-letubby

20
Có một đối số dòng lệnh để tắt điều này? Hay đây là một tính năng không thể thay đổi?
Ethan Bierlein

26
FWIW, tôi đã có những lúc đọc mã của người khác, nhưng chắc chắn không phải do các biểu tượng không được sử dụng. OTOH, hôm nay tôi đã mất một giờ để điều tra các phương pháp để đối phó với "tính năng" #% $ golang này.
Torsten Bronger

24
Đáng buồn thay câu trả lời này là chính xác - nhưng điều đó không biện minh cho nó. Có một thế giới khác biệt giữa kiểm tra mã và chỉ cần thực thi nó. Khi chúng tôi kiểm tra mã, chúng tôi sử dụng linters để bắt lỗi loại này. Khi chúng tôi thực hiện trong quá trình phát triển nhanh chóng, chúng tôi không có cùng tiêu chuẩn. Không thể tha thứ để nhầm lẫn một trình biên dịch với một kẻ nói dối. Ngay cả cảnh sát phong cách trong Google cũng không phạm sai lầm đó.
Travis Wilson

29

Bạn có thể sử dụng một "hàm null" đơn giản cho việc này, ví dụ:

func Use(vals ...interface{}) {
    for _, val := range vals {
        _ = val
    }
}

Mà bạn có thể sử dụng như vậy:

package main

func main() {
    a := "declared and not used"
    b := "another declared and not used"
    c := 123

    Use(a, b, c)
}

Ngoài ra còn có một gói cho việc này để bạn không phải xác định Usechức năng mỗi lần:

import (
  "github.com/lunux2008/xulu"
)

func main() {
  // [..]

  xulu.Use(a, b, c)
}

29

Theo các câu hỏi thường gặp :

Một số người đã yêu cầu một tùy chọn trình biên dịch để tắt các kiểm tra đó hoặc ít nhất là giảm chúng thành các cảnh báo. Tuy nhiên, một tùy chọn như vậy chưa được thêm vào, bởi vì các tùy chọn trình biên dịch sẽ không ảnh hưởng đến ngữ nghĩa của ngôn ngữ và vì trình biên dịch Go không báo cáo cảnh báo, chỉ có các lỗi ngăn cản quá trình biên dịch.

Có hai lý do để không có cảnh báo. Đầu tiên, nếu nó đáng để phàn nàn, thì nó đáng để sửa trong mã. (Và nếu nó không đáng để sửa, thì cũng không đáng để nói

Tôi không nhất thiết phải đồng ý với điều này vì nhiều lý do không đáng để tham gia. Đó là những gì nó có, và nó không có khả năng thay đổi trong tương lai gần.

Đối với các gói, có goimportscông cụ tự động thêm các gói bị thiếu và loại bỏ các gói không sử dụng. Ví dụ:

# Install it
$ go get golang.org/x/tools/cmd/goimports

# -w to write the source file instead of stdout
$ goimports -w my_file.go

Bạn sẽ có thể chạy nó từ bất kỳ trình soạn thảo nửa chừng nào - ví dụ cho Vim:

:!goimports -w %

Các goimportsliệt kê một số lệnh cho biên tập viên khác, và bạn thường thiết lập nó để chạy tự động khi bạn tiết kiệm bộ đệm vào đĩa.

Lưu ý rằng goimportscũng sẽ chạy gofmt.


Như đã được đề cập, đối với các biến, cách dễ nhất là (tạm thời) gán chúng cho _:

// No errors
tasty := "ice cream"
horrible := "marmite"

// Commented out for debugging
//eat(tasty, horrible)

_, _ = tasty, horrible

9

Một góc không được đề cập cho đến nay là bộ công cụ được sử dụng để chỉnh sửa mã.

Sử dụng Visual Studio Code cùng với Tiện ích mở rộng từ lukehoban được gọi Gosẽ thực hiện một số phép thuật tự động cho bạn. Tiện ích mở rộng Go tự động chạy gofmt, golintv.v., loại bỏ và thêm importcác mục . Vì vậy, ít nhất là phần đó bây giờ là tự động.

Tôi sẽ thừa nhận nó không phải là 100% giải pháp cho câu hỏi, nhưng đủ hữu ích.


8

Trong trường hợp những người khác có một thời gian khó hiểu về điều này, tôi nghĩ rằng nó có thể giúp giải thích nó bằng những thuật ngữ rất đơn giản. Nếu bạn có một biến mà bạn không sử dụng, ví dụ như một hàm mà bạn đã nhận xét lời gọi (trường hợp sử dụng phổ biến):

myFn := func () { }
// myFn()

Bạn có thể gán một biến vô dụng / trống cho hàm để nó không còn được sử dụng :

myFn := func () { }
_ = myFn
// myFn()
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.