gogolint

golint execution returns nothing


I'm coding exercise for exercism.io. And my mentor said that my code should be checked by some go linters, and he suggested me to try golint and golangci-lint. I installed golint via go get -u golang.org/x/lint/golint, and started it:

rustam:hamming $ golint hamming.go 
rustam:hamming $ 

but it returns nothing. Also if I use golangci-lint there is same result — just nothing. And I have no idea why.

There is my code, full of style mistakes:

// Package hamming is Exercism.io exercise
package hamming

import "errors"

// Distance — Calculating Hamming Distance for two DNA strands
func Distance(a, b string) (int, error) {

    if len(a) != len(b) {
        return 0, errors.New("Strands should be equal size")
    }

    if len(a) == 0 || len(b) == 0 {
        return 0, nil
    }

    var hd int = 0

    for i := 0; i < len(a); i++ {
        if a[i] != b[i] {
            hd++
        }
    }

    return hd, nil
}

And there is my go env:

rustam:hamming $ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN="/Users/rustam/go/bin"
GOCACHE="/Users/rustam/Library/Caches/go-build"
GOENV="/Users/rustam/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/rustam/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go/1.13.4/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.13.4/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/4j/4rjv22zs1pb68wssv5gn2wfw0000gn/T/go-build148685464=/tmp/go-build -gno-record-gcc-switches -fno-common"

and my ~/.bash_profile

export GOPATH=$HOME/go
export GOBIN=$HOME/go/bin
export PATH=$PATH:$GOPATH/bin

I'd appreciate it if you could point out my mistakes.


Solution

  • In Go, the minimal checks might be the Go tools, go fmt, go vet, and golint.

    Here is a minimum, reproducible example (see How to create a Minimal, Reproducible Example) that shows that your hamming.go program passes all current checks.

    Command golint

    $ go version
    go version devel +075c20cea8 Thu Dec 26 13:53:31 2019 +0000 linux/amd64
    $ go fmt hamming.go
    $ go vet hamming.go
    $ go get -u golang.org/x/lint/golint
    go: downloading golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f
    go: found golang.org/x/lint/golint in golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f
    go: downloading golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f
    go: golang.org/x/tools upgrade => v0.0.0-20191226230302-065ed046f11a
    go: downloading golang.org/x/tools v0.0.0-20191226230302-065ed046f11a
    $ golint hamming.go
    $ cat hamming.go
    // Package hamming is Exercism.io exercise
    package hamming
    
    import "errors"
    
    // Distance — Calculating Hamming Distance for two DNA strands
    func Distance(a, b string) (int, error) {
    
        if len(a) != len(b) {
            return 0, errors.New("Strands should be equal size")
        }
    
        if len(a) == 0 || len(b) == 0 {
            return 0, nil
        }
    
        var hd int = 0
    
        for i := 0; i < len(a); i++ {
            if a[i] != b[i] {
                hd++
            }
        }
    
        return hd, nil
    }
    $
    

    Comment: My mentor send his linter execution and there was some messages like

    $ golint hamming.go hamming.go:17:15: 
    should drop = 0 from declaration of var hd; it is the zero value 
    

    – Rustery

    Your mentor is using an old, obsolete version of golint. For the current version, they should run

    go get -u golang.org/x/lint/golint
    

    Has your mentor explained the limited purpose of golint? For example, "Golint is not perfect, and has both false positives and false negatives. Do not treat its output as a gold standard."

    Golint is a linter for Go source code.

    Purpose

    Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes.

    Golint differs from govet. Govet is concerned with correctness, whereas golint is concerned with coding style. Golint is in use at Google, and it seeks to match the accepted style of the open source Go project.

    The suggestions made by golint are exactly that: suggestions. Golint is not perfect, and has both false positives and false negatives. Do not treat its output as a gold standard. We will not be adding pragmas or other knobs to suppress specific warnings, so do not expect or require code to be completely "lint-free". In short, this tool is not, and will never be, trustworthy enough for its suggestions to be enforced automatically, for example as part of a build process. Golint makes suggestions for many of the mechanically checkable items listed in Effective Go and the CodeReviewComments wiki page.


    Here is my attempt at a solution:

    package hamming
    
    import "errors"
    
    // Distance returns the Hamming distance for two DNA strings of equal length.
    // DNA strings are constructed from the alphabet {A, C, G, T}.
    func Distance(a, b string) (int, error) {
        if len(a) != len(b) {
            return 0, errors.New("strings should be of equal length")
        }
    
        d := 0
        for i := 0; i < len(a); i++ {
            if a[i] != b[i] {
                d++
            }
        }
        return d, nil
    }