Como evitar erros irritantes "declarados e não usados"


238

Estou aprendendo o Go, mas acho um pouco chato que, ao compilar, não deixe nenhuma variável ou pacote sem uso.

Isso realmente está me atrasando bastante. Por exemplo, eu só queria declarar um novo pacote e planejar usá-lo mais tarde ou apenas descomentar algum comando para testar. Eu sempre recebo o erro e preciso comentar todos esses usos.

Existe alguma maneira de evitar esse tipo de check-in no Go?


1
Você também pode usar o goimports ( godoc.org/code.google.com/p/go.tools/cmd/goimports ) para adicionar / remover automaticamente importações para você.
Elithrar


3
Ainda sinto que uma opção do compilador seria útil para o fluxo de trabalho "Quero comentar algo para ajudar na depuração".
RJFalconer

13
Esse recurso é uma ótima maneira de desperdiçar o tempo das pessoas, lol, qual é o objetivo? Quando você confirma / envia o código, ok não há vars não utilizados, mas ao desenvolvê-lo? Horrível.
Alexander Mills

É 2020 e não acredito que eles ainda não tenham corrigido isso (nem mesmo com um sinalizador de compilador). Eu fiz um projeto no Go há cerca de 5 anos e gostei do idioma em geral, mas era inutilizável para mim apenas por causa disso. A maneira como codifico, estou constantemente comentando / comentando coisas, então esse "recurso" no Go faz com que as coisas demorem o dobro do tempo para mim ... Voltei a verificar a cada poucos meses desde então para ver se um senso de razão ultrapassou a equipe Go, e até agora sem sorte ... É uma merda. Caso contrário, é uma ótima linguagem e eu adoraria usá-la mais, mas atualmente não é utilizável para mim.
Ruslan

Respostas:


235

Esse erro está aqui para forçá-lo a escrever um código melhor e não se esqueça de usar tudo o que declarar ou importar. Isso facilita a leitura do código escrito por outras pessoas (você sempre tem certeza de que todas as variáveis ​​declaradas serão usadas) e evita possíveis códigos mortos.

Mas, se você realmente quiser pular esse erro, poderá usar o identificador em branco ( _):

package main

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

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

torna-se

package main

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

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

Como dito por kostix nos comentários abaixo, você pode encontrar a posição oficial da equipe Go nas Perguntas frequentes :

A presença de uma variável não utilizada pode indicar um erro, enquanto as importações não utilizadas apenas diminuem a compilação. Acumule importações não utilizadas suficientes na sua árvore de códigos e as coisas podem ficar muito lentas. Por esses motivos, o Go não permite nenhum.


90
Ainda assim, isso não é tão diferente de comentar. E entendo que isso é para um código melhor, mas seria melhor se pudéssemos fechar uma verificação do motivo pelo qual testamos nosso código e depois abrir essa verificação novamente depois que quisermos terminar o código e torná-lo limpo?
A-letubby

21
@ kostix Bem ... pode não atrasá-lo, porque você pode ser um especialista, mas é para mim e para a maneira como estou codificando. Eu só estou querendo saber se existe uma maneira melhor. Mas de qualquer forma, obrigado pelo FAQ! Ao ler isso, posso entender totalmente por que razões o golang está fazendo dessa maneira.
A-letubby

20
Existe um argumento na linha de comando para desativar isso? Ou esse é um recurso imutável?
Ethan Bierlein

26
FWIW, passei maus momentos lendo código de outras pessoas, mas definitivamente não devido a símbolos não utilizados. OTOH, perdi uma hora hoje investigando métodos para lidar com esse * #% $ golang "recurso".
Torsten Bronger

24
Infelizmente, essa resposta está correta - mas isso não justifica. Há um mundo de diferença entre fazer check-in do código e simplesmente executá-lo. Quando fazemos o check-in do código, usamos linters para capturar esse tipo de erro. Quando executamos durante o desenvolvimento rápido, não temos os mesmos padrões. É imperdoável confundir um compilador com um linter. Mesmo o estilo policial no Google não comete esse erro.
Travis Wilson

29

Você pode usar uma "função nula" simples para isso, por exemplo:

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

Que você pode usar assim:

package main

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

    Use(a, b, c)
}

também um pacote para isso, para que você não precise definir a Usefunção todas as vezes:

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

func main() {
  // [..]

  xulu.Use(a, b, c)
}

29

De acordo com o FAQ :

Alguns pediram uma opção do compilador para desativar essas verificações ou pelo menos reduzi-las a avisos. Essa opção não foi adicionada, no entanto, porque as opções do compilador não devem afetar a semântica do idioma e porque o compilador Go não relata avisos, apenas erros que impedem a compilação.

Há duas razões para não haver avisos. Primeiro, se vale a pena reclamar, vale a pena fixar no código. (E se não vale a pena consertar, não vale a pena mencionar.) Segundo, fazer com que o compilador gere avisos incentiva a implementação a avisar sobre casos fracos que podem fazer barulho na compilação, mascarando erros reais que devem ser corrigidos.

Não concordo necessariamente com isso por várias razões que não valem a pena. É o que é e não é provável que mude no futuro próximo.

Para pacotes, existe a goimportsferramenta que adiciona automaticamente pacotes ausentes e remove os não utilizados. Por exemplo:

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

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

Você deve poder executar isso a partir de qualquer editor decente incompleto - por exemplo, para o Vim:

:!goimports -w %

A goimportspágina lista alguns comandos para outros editores e você normalmente o define para ser executado automaticamente quando você salva o buffer no disco.

Observe que goimportstambém será executado gofmt.


Como já foi mencionado, para variáveis, a maneira mais fácil é atribuí-las (temporariamente) a _:

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

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

_, _ = tasty, horrible

9

Um ângulo não mencionado até agora são os conjuntos de ferramentas usados ​​para editar o código.

Usar o Código do Visual Studio junto com a Extensão de lukehoban chamada Gofará uma mágica automática para você. A extensão Go executa automaticamente gofmt, golintetc, e remove e adiciona importentradas . Então, pelo menos essa parte agora é automática.

Vou admitir que não é 100% da solução para a pergunta, mas por mais útil que seja.


8

Caso outras pessoas tenham dificuldade em entender isso, acho que pode ajudar a explicá-lo em termos muito diretos. Se você tem uma variável que não usa, por exemplo, uma função para a qual você comentou a chamada (um caso de uso comum):

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

Você pode atribuir uma variável inútil / em branco à função para que ela não seja mais usada :

myFn := func () { }
_ = myFn
// myFn()
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.