<p>For more than a year I've been lurking on Go-related forums, browsing repos with software written in Go and writing my own software in Go.</p>
<p>Yet, the most common types of mistakes I see, not only made by beginners, but by some moderately experienced gophers are:</p>
<ul>
<li>unchecked errors;</li>
<li>exported interfaces, structs, methods and functions without comments;</li>
<li>impropely named variables(even with underscores in them, i.e. <em>some_variable</em>).</li>
</ul>
<p>This all is rather amusing, since there are linters that can detect those errors for you automatically:</p>
<ul>
<li>Unchecked errors — <a href="https://github.com/kisielk/errcheck">errcheck</a>;</li>
<li>Missing comments and many more — <a href="https://github.com/golang/lint">golint</a>;</li>
<li>Unused struct fields/variables and space wasted, because of suboptimal struct layout — <a href="https://github.com/opennota/check">structcheck, varcheck, aligncheck</a>;</li>
<li>Unnecessary conversions — <a href="https://github.com/mdempsky/unconvert">unconvert</a>.</li>
</ul>
<p>Or, if you want to CHECK ALL THE THINGS — <a href="https://github.com/alecthomas/gometalinter">gometalinter</a>.</p>
<p>Some of those linters can be integrated in your favorite editor(read repo's <strong>README</strong> or <em>google</em>). Enjoy.</p>
<hr/>**评论:**<br/><br/>n1ghtm4n: <pre><p>Let us not forget <a href="https://github.com/dominikh/go-tools"><code>staticcheck</code>, <code>gosimple</code>, and <code>unused</code></a>. These should be mandatory in any CI system.</p></pre>Southclaw: <pre><p>I started writing Go a couple of months ago for my company. Learnt the language and started writing a pretty important part of our infrastructure in a matter of weeks thanks to all the amazing tools available for checking source code. They aren't just good for development but they helped me learn all the little quirks and unique things about the language in a very short amount of time!</p>
<p>That being said, GoMetaLinter runs very slow on my system (about a minute) so I stay away from that in my editor and just use it for pre-commit cleanup. I mainly stick with <code>golint</code> for lint-on-save as it finishes in seconds and doesn't stop the flow of writing.</p></pre>alecthomas: <pre><p>Hello, I'm the author of gometalinter. Unfortunately more and more linters are becoming slower and slower. You can run gometalinter with --fast to exclude these, but at this stage that is most of them :(</p></pre>Swimbo: <pre><p>Still faster than committing a bug. </p></pre>therocketofpoop: <pre><p>Still faster than debugging a bug.</p></pre>goomba_gibbon: <pre><p>Still faster than catching things in a code review too.</p></pre>dominikh: <pre><p>You can have interesting linters, or you can have fast linters.</p>
<p>The only checks that are as fast as you'd like them to be are trivial AST-based checks, which only get you so far. Anything that is supposed to catch actual bugs will have to do work similar to, if not more complex than, the compiler.</p>
<p>Of course nobody is saying that all linters need to be run every 5 seconds in your editor. Use them in your commit hooks or in CI, or run them once every night on your code base.</p>
<p>Even the slow tools are still way faster than those in other languages.</p></pre>GaidinTS: <pre><p>yeah I think that's fine. There's really too levels of linting anyway; when you're coding, and want to lint on the fly / on save, and in your CI pipeline.</p></pre>nos69: <pre><p>Is it possible for the VSCode metalinter to configure that only the open files are linted? Or just use the standard linter and run the meta linter by hand from VSCode?</p>
<p>It takes a while every time I save when I have the meta linter active, because he runs his checks on all files in the directory and I don't want that.</p></pre>alecthomas: <pre><p>That is not possible because the linters themselves typically act on entire packages. I would suggest passing <code>--fast</code> through your config somehow, that will make a huge difference.</p></pre>nos69: <pre><p>But doesn't --fast then skip certain checks?</p></pre>alecthomas: <pre><p>Yes, but for a linter in your editor it doesn't matter that much. You just want to catch the grossest of errors there, then run the full suite of linters in a pre-commit hook, or in your CI.</p></pre>jeremiahs_bullfrog: <pre><p>I use gometalinter every month or so and batch-fix whatever it finds. Like you said, it's far to slow to use as a regular part of development.</p></pre>robertmeta: <pre><p>I run it at least daily, because it can legitimately help me head off errors before they become an issue.</p></pre>jeremiahs_bullfrog: <pre><p>Eh, I've been developing Go for a few years now, so it's mostly just eliminating warnings now for me (mostly intentionally ignored errors). But I do occasionally see value in it.</p></pre>tmornini: <pre><p>gometalinter --fast</p></pre>kisielk: <pre><p>Fun fact: I created errcheck as a way to learn to use the go/types package, back when it was first announced. I never really expected anyone to start using it, but as with all my personal projects I threw it up on GitHub in case someone found it useful. 4 years later it seems some people still do!</p></pre>lunarsunrise: <pre><p>Thank you for sharing it! <code>errcheck</code> is in the set of "lowest-common-denominator"/"there-really-is-no-excuse" linters that we've set up to break builds at work; it may be a simple tool, but it's an invaluable low-pass filter in our CI and code review processes, and great in combination with editor integration!</p></pre>goomba_gibbon: <pre><p>Reminds me of DOTADIW, or "Do One Thing and Do It Well."</p>
<p>It's a perfect example of a tool that does just that!</p></pre>klauspost: <pre><p>Thanks - I use it on a regular basis. I even modified it to check if all returned values of another specific type was always assigned. </p></pre>rwbcxrz: <pre><p>gometalinter is great, but I think w.r.t. linters, Go would benefit from having something more modular/pluggable like JS's eslint. Might be easier to build once the plugin API is available on more platforms.</p></pre>alecthomas: <pre><p>I'm the author of gometalinter, and I agree. Gometalinter is a hack around a problem, not a final solution. </p>
<p>A common linter framework/driver would be ideal. I think it would really encourage people to write new linters as well.</p></pre>whizack: <pre><p>i use gometalinter in vscode and it's the best... it can get a little crazy with errors sometimes, but it's all good information that reminds me to do the right things.</p></pre>dominikh: <pre><p>Please don't run/listen to aligncheck indiscriminately. In the general case, suboptimal (in terms of memory usage) layout is irrelevant, and inferior to meaningful ordering of fields. And in specific cases, the "optimal" (again in terms of memory usage) layout is very suboptimal due to false sharing. </p>
<p>It's a tool that should be used on specific types in specific scenarios.</p></pre>jmoiron: <pre><p>It's unfortunate that so many of the great go source analysis tools break down when your project uses cgo.</p></pre>dominikh: <pre><p>That changed a couple months ago, at least for tools that use x/tools/go/loader. Nowadays, go/loader does the same cgo preprocessing that go build does, i.e. it invokes C compilers and generates the appropriate Go code.</p>
<p>Some tools may report funky line numbers (which can be fixed), but they won't fail to check your code anymore.</p></pre>shovelpost: <pre><p>Even more unfortunate when we are forced to use cgo.</p></pre>Lord_NShYH: <pre><p>I have a section in my Makefile to fmt and lint my Go projects. Then, I set it up as a pre-commit hook. Easy.</p></pre>Spirit_of_Stallman: <pre><p>Alarm! Calling technicians in sector 4! A leak in the cryochamber "codesenberg" was detected.</p>
<p>// first gometaliter commit: Aug 5, 2014</p></pre>Yojihito: <pre><blockquote>
<p>impropely named variables(even with underscores in them, i.e. some_variable).</p>
</blockquote>
<p>Isn't it just convention if I name my variables</p>
<pre><code>someVariableFoo
some_Variable_Foo
some_variable_foo
</code></pre>
<p>?</p></pre>Orange_Tux: <pre><p>I use errcheck, go vet and golint like below (piece from a Makefile):</p>
<pre><code>PACKAGES=$(shell go list ./... | grep -v /vendor)
check: ## Check the code using various linters and static checkers.
@echo "Running gofmt..."
@gofmt -d $(shell find . -type f -name '*.go' -not -path "./vendor/*")
@echo "Running go vet..."
@for package in $(PACKAGES); do \
go vet -v $$package || exit 1; \
done
@echo "Running golint..."
@for package in $(PACKAGES); do \
golint -set_exit_status $$package || exit 1; \
done
@echo "Running errcheck..."
@for package in $(PACKAGES); do \
errcheck -ignore 'Close' -ignoretests $$package || exit 1; \
done
</code></pre></pre>anacrolix: <pre><p>errcheck is the only one that actually prevents bugs. unconvert might help catch refactoring bugs in the future. That's it. Most Go linters are obnoxious and pedantic. </p></pre>goomba_gibbon: <pre><p>I disagree. You are completely discounting the value of having consistent, idiomatic, well-documented, readable code.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传