「宣言されて使用されない」という迷惑なエラーを回避する方法


238

私はGoを学習していますが、コンパイルするときに変数やパッケージを未使用のままにしてはいけないのは少し面倒です。

これは本当に私をかなり遅くしています。たとえば、新しいパッケージを宣言して後で使用するか、テストするコマンドのコメントを外したいだけです。私はいつもエラーが出るので、それらすべての使い方についてコメントする必要があります。

Goでこの種のチェックを回避する方法はありますか?


1
goimports(godoc.org/code.google.com/p/go.tools/cmd/goimports)を使用して、インポートを自動的に追加/削除することもできます。
elithrar 2014


3
「デバッグを支援するためにコメントアウトしたい」ワークフローには、コンパイラオプションが役立つと思います。
RJFalconer 2017年

13
この機能は人々の時間を無駄にするのに最適な方法です笑、ポイントは何ですか?コードをコミットまたは出荷するとき、使用されていない変数はありませんが、それを開発するときはどうですか?恐ろしい。
Alexander Mills

それは2020年であり、彼らがまだこれを修正していないとは信じられません(コンパイラフラグでさえも)。私は5年ほど前にGoでプロジェクトを行い、全体的に言語が好きでしたが、それだけで私には使用できませんでした。コーディング方法は常にコメント/コメント解除しているので、Goのこの「機能」により、処理に2倍の時間がかかります...それ以来、数か月ごとに、理由の感覚が追いついていないかチェックしています。囲碁チーム、そしてこれまでのところ運がない... それ以外の場合は素晴らしい言語なので、もっと使いたいのですが、現在は私には使えません。
ルスラン

回答:


235

そのエラーは、より良いコードを書くように強制するためのものであり、宣言またはインポートするすべてのものを使用するようにしてください。他の人が書いたコードを読みやすくし(宣言されたすべての変数が使用されることを常に確信しています)、デッドコードの可能性を回避します。

ただし、このエラーを本当にスキップしたい場合は、空白の識別子_)を使用できます。

package main

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

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

なる

package main

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

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

以下のコメントでkostixが述べたように、FAQで Goチームの公式ポジションを見つけることができます。

未使用の変数の存在はバグを示している可能性がありますが、未使用のインポートはコンパイルを遅くするだけです。コードツリーに十分な未使用のインポートを蓄積すると、処理が非常に遅くなる可能性があります。これらの理由により、Goではどちらも許可されていません。


90
それでも、これはコメントアウトするのとそれほど変わりません。そして、私はこれがより良いコードのためであることを理解していますが、コードでテストする理由のチェックを閉じ、コードを完成させてクリーンにしたい後で、このチェックを再度開くことができればもっと良いでしょうか?
A-letubby 2014

21
@kostixまあ..あなたはエキスパートかもしれないので、あなたを遅くすることはないかもしれませんが、それは私と私がコーディングしている方法のためです。より良い方法があるかどうか私はちょうど疑問に思っています。とにかく、FAQをありがとう!これを読むことで、golangがこのように行っている理由を完全に理解できます。
A-letubby 2014

20
これをオフにするコマンドライン引数はありますか?または、これは変更できない機能ですか?
Ethan Bierlein 2015年

26
FWIW、私は他人のコードを読むのに苦労しましたが、未使用のシンボルが原因ではありません。OTOH、私は今日、この*#%$ golangの「機能」に対処する方法を調査している1時間を失いました。
Torsten Bronger、2016年

24
悲しいことに、この答えは正しいです-しかし、それはそれを正当化しません。コードをチェックインすることと単純にそれを実行することの間には違いの世界があります。コードをチェックインするとき、この種のエラーをキャッチするためにリンターを使用します。迅速な開発中に実行する場合、同じ基準はありません。コンパイラとリンターを混同することは許されません。グーグル内のスタイルの警察でさえ、その間違いを犯さない。
Travis Wilson

29

これには簡単な「null関数」を使用できます。次に例を示します。

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

あなたはそのように使用できます:

package main

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

    Use(a, b, c)
}

あります。このためパッケージには、ユーザーが定義する必要はありませんので、Use機能を毎回:

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

func main() {
  // [..]

  xulu.Use(a, b, c)
}

29

FAQによると:

一部のユーザーは、これらのチェックをオフにするか、少なくとも警告を表示しないようにするコンパイラオプションを求めています。ただし、コンパイラオプションは言語のセマンティクスに影響を与えないため、Goコンパイラは警告を報告せず、コンパイルを妨げるエラーのみを報告するため、このようなオプションは追加されていません。

警告がない理由は2つあります。まず、文句を言う価値がある場合は、コードを修正する価値があります。(そして、修正する価値がない場合は、言及する価値がありません。)2番目に、コンパイラーに警告を生成させると、実装に、ノイズの多いコンパイルを作成する可能性がある弱いケースについて警告し、修正すべき実際のエラーをマスクします。

検討する価値がないさまざまな理由で、私は必ずしもこれに同意しません。それがそうであり、近い将来変更される可能性は低いです。

パッケージについてgoimportsは、不足しているパッケージを自動的に追加し、未使用のパッケージを削除するツールがあります。例えば:

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

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

中途半端なエディタからこれを実行できるはずです-例えばVimの場合:

:!goimports -w %

このgoimportsページには他のエディター用のコマンドがいくつかリストされており、通常は、バッファーをディスクに保存するときに自動的に実行されるように設定します。

goimportsも実行されることに注意してくださいgofmt


すでに述べたように、変数の場合、最も簡単な方法は(一時的に)変数を次のように割り当てること_です。

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

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

_, _ = tasty, horrible

9

これまでに言及されていない1つの角度は、コードの編集に使用されるツールセットです。

呼び出されたlukehobanの拡張機能と共にVisual Studio Codeを使用すると、いくつかの自動マジックが実行されます。囲碁の拡張子が自動的に実行されます、など、および削除し、追加のエントリをGogofmtgolintimport。したがって、少なくともその部分は自動化されています。

質問に対する100%の解決策ではありませんが、十分に役立ちます。


8

他の人がこれを理解するのに苦労している場合、私はそれを非常に簡単な言葉で説明するのに役立つかもしれないと思います。呼び出しをコメントアウトした関数など、使用しない変数がある場合(一般的な使用例):

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

それはもはやだようにするには、関数に役に立たない/空白の変数を割り当てることはできません使用されていません

myFn := func () { }
_ = myFn
// myFn()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.