Cómo evitar errores molestos "declarados y no utilizados"


238

Estoy aprendiendo Go, pero creo que es un poco molesto que al compilar no deje ninguna variable o paquete sin usar.

Esto realmente me está frenando bastante. Por ejemplo, solo quería declarar un nuevo paquete y planear usarlo más tarde o simplemente descomentar algún comando para probar. Siempre recibo el error y necesito comentar todos esos usos.

¿Hay alguna forma de evitar este tipo de verificación en Go?


1
También puede usar goimports ( godoc.org/code.google.com/p/go.tools/cmd/goimports ) para agregar / eliminar importaciones automáticamente.
elithrar


3
Sigo sintiendo que una opción de compilador sería útil para el flujo de trabajo "Quiero comentar algo para ayudar a la depuración".
RJFalconer

13
Esta característica es una excelente manera de perder el tiempo de las personas jajaja, ¿cuál es el punto? Cuando confirma / envía el código, está bien, no hay vars no utilizados, pero ¿cuándo lo desarrolla? Horrible.
Alexander Mills

Es 2020 y no puedo creer que todavía no hayan solucionado esto (ni siquiera con un indicador del compilador). Hice un proyecto en Go hace aproximadamente 5 años y, en general, me gustó el idioma, pero no me fue posible utilizarlo solo por esto. La forma en que codifico estoy constantemente comentando / descomentando cosas, por lo que esta "característica" en Go hace que las cosas tomen el doble de tiempo para mí ... He estado revisando cada pocos meses desde entonces para ver si una razón me ha sobrepasado. el equipo de Go, y hasta ahora sin suerte ... apesta. De lo contrario, es un gran idioma y me encantaría usarlo más, pero actualmente no lo puedo usar.
Ruslan

Respuestas:


235

Ese error está aquí para obligarlo a escribir un mejor código y asegúrese de usar todo lo que declare o importe. Hace que sea más fácil leer el código escrito por otras personas (siempre está seguro de que se usarán todas las variables declaradas) y evita algunos posibles códigos muertos.

Pero, si realmente quiere omitir este error, puede usar el identificador en blanco ( _):

package main

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

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

se convierte

package main

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

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

Como dijo kostix en los comentarios a continuación, puede encontrar la posición oficial del equipo Go en las preguntas frecuentes :

La presencia de una variable no utilizada puede indicar un error, mientras que las importaciones no utilizadas solo ralentizan la compilación. Acumule suficientes importaciones no utilizadas en su árbol de códigos y las cosas pueden volverse muy lentas. Por estas razones, Go no permite ninguno.


90
Aún así, esto no es tan diferente de comentarlo. Y, entiendo que esto es para un mejor código, pero ¿sería mejor si podemos cerrar un cheque por qué probar nuestro código y luego abrir este cheque nuevamente después de que queramos terminar el código y limpiarlo?
A-letubby

21
@kostix Bueno ... puede que no te ralentice porque podrías ser un experto, pero es para mí y la forma en que estoy codificando. Me pregunto si hay una mejor manera. Pero de todos modos, ¡gracias por las preguntas frecuentes! Al leer esto, puedo entender totalmente por qué razones Golang está haciendo de esta manera.
A-letubby

20
¿Hay un argumento de línea de comandos para desactivar esto? ¿O es esta una característica inmutable?
Ethan Bierlein

26
FWIW, he tenido malos momentos leyendo el código de otros, pero definitivamente no debido a símbolos no utilizados. OTOH, perdí una hora hoy investigando métodos para lidiar con esta "característica" de golang * #% $.
Torsten Bronger

24
Lamentablemente, esta respuesta es correcta, pero eso no lo justifica. Hay un mundo de diferencia entre registrar el código y simplemente ejecutarlo. Cuando registramos el código, usamos linters para detectar este tipo de error. Cuando ejecutamos durante el desarrollo rápido, no tenemos los mismos estándares. Es imperdonable confundir un compilador con un linter. Incluso el estilo policial dentro de Google no comete ese error.
Travis Wilson

29

Puede usar una simple "función nula" para esto, por ejemplo:

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

Que puedes usar así:

package main

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

    Use(a, b, c)
}

También hay un paquete para esto, por lo que no tiene que definir la Usefunción cada vez:

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

func main() {
  // [..]

  xulu.Use(a, b, c)
}

29

De acuerdo con las preguntas frecuentes :

Algunos han pedido una opción de compilación para desactivar esas comprobaciones o al menos reducirlas a advertencias. Sin embargo, dicha opción no se ha agregado porque las opciones del compilador no deberían afectar la semántica del lenguaje y porque el compilador Go no informa advertencias, solo errores que impiden la compilación.

Hay dos razones para no tener advertencias. Primero, si vale la pena quejarse, vale la pena arreglarlo en el código. (Y si no vale la pena arreglarlo, no vale la pena mencionarlo). En segundo lugar, hacer que el compilador genere advertencias alienta la implementación para advertir sobre casos débiles que pueden hacer que la compilación sea ruidosa, enmascarando errores reales que deberían corregirse.

No estoy necesariamente de acuerdo con esto por varias razones por las que no vale la pena entrar. Es lo que es, y no es probable que cambie en el futuro cercano.

Para los paquetes, existe la goimportsherramienta que agrega automáticamente los paquetes que faltan y elimina los que no se utilizan. Por ejemplo:

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

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

Debería poder ejecutar esto desde cualquier editor decente a mitad de camino, por ejemplo, para Vim:

:!goimports -w %

La goimportspágina enumera algunos comandos para otros editores, y normalmente lo configura para que se ejecute automáticamente cuando guarda el búfer en el disco.

Tenga en cuenta que goimportstambién se ejecutará gofmt.


Como ya se mencionó, para las variables la forma más fácil es asignarlas (temporalmente) a _:

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

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

_, _ = tasty, horrible

9

Un ángulo no mencionado hasta ahora es el conjunto de herramientas utilizadas para editar el código.

El uso de Visual Studio Code junto con la extensión de lukehoban llamada Gohará algo de magia automática para usted. La extensión Go se ejecuta automáticamente gofmt, golintetc., y elimina y agrega importentradas . Entonces, al menos esa parte ahora es automática.

Admitiré que no es el 100% de la solución a la pregunta, pero lo suficientemente útil.


8

En caso de que otros tengan dificultades para dar sentido a esto, creo que podría ser útil explicarlo en términos muy directos. Si tiene una variable que no utiliza, por ejemplo, una función para la que ha comentado la invocación (un caso de uso común):

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

Puede asignar una variable inútil / en blanco a la función para que ya no se use :

myFn := func () { }
_ = myFn
// myFn()
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.