Как избежать надоедливой ошибки «объявлена ​​и не использована»


238

Я изучаю Go, но мне немного досадно, что при компиляции я не должен оставлять ни одну переменную или пакет неиспользованным.

Это действительно довольно сильно замедляет меня. Например, я просто хотел объявить новый пакет и планировать использовать его позже или просто раскомментировать некоторую команду для тестирования. Я всегда получаю сообщение об ошибке, и мне нужно прокомментировать все эти варианты использования.

Есть ли способ избежать такой проверки в Go?


1
Вы также можете использовать goimports ( godoc.org/code.google.com/p/go.tools/cmd/goimports ) для автоматического добавления / удаления импортируемых файлов .
elithrar


3
Я все еще чувствую, что опция компилятора будет полезна для рабочего процесса «Я хочу что-то закомментировать, чтобы помочь отладке».
RJFalconer

13
Эта особенность - отличный способ тратить время людей. Какой смысл? Когда вы фиксируете / отправляете код, хорошо, что неиспользуемые переменные - это хорошо, но при разработке? Какой ужас.
Александр Миллс

Это 2020 год, и я не могу поверить, что они до сих пор не исправили это (даже с флагом компилятора). Я сделал проект в Go около 5 лет назад, и в целом язык мне понравился, но он был непригоден для меня только из-за этого. То, как я кодирую, я постоянно комментирую / раскомментирую, так что эта «особенность» в Go заставляет вещи удваивать время для меня ... С тех пор я проверяю каждые несколько месяцев, чтобы понять, не преодолено ли чувство причины. Команда Go, и до сих пор не повезло ... Отстой. В противном случае это отличный язык, и я бы хотел использовать его чаще, но в настоящее время он просто не пригоден для меня.
Руслан

Ответы:


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 в комментариях ниже, вы можете найти официальную позицию команды Go в FAQ :

Наличие неиспользуемой переменной может указывать на ошибку, в то время как неиспользуемый импорт просто замедляет компиляцию. Накопите достаточно неиспользованных импортов в вашем дереве кода, и все может стать очень медленным. По этим причинам Go не позволяет ни того, ни другого.


90
Тем не менее, это не так уж и отличается от комментирования. И я понимаю, что это для лучшего кода, но было бы лучше, если бы мы могли закрыть проверку, почему тестирование нашего кода, а затем снова открыть эту проверку после того, как мы хотим закончить код и сделать его чистым?
A-letubby

21
@kostix Ну ... это может не замедлить вас, потому что вы можете быть экспертом, но это для меня и моего кодирования. Мне просто интересно, есть ли лучший способ. Но все равно спасибо за FAQ! Прочитав это, я могу полностью понять, по каким причинам Голанг так поступает.
A-letubby

20
Есть ли аргумент командной строки, чтобы отключить это? Или это неизменяемая функция?
Итан Бирляйн

26
FWIW, у меня были плохие времена, читая код других, но определенно не из-за неиспользованных символов. OTOH, я потерял час сегодня, исследуя методы, чтобы справиться с этой * #% $ golang "функцией".
Торстен Бронджер

24
К сожалению, этот ответ правильный, но это не оправдывает его. Существует большая разница между проверкой кода и простым его выполнением. Когда мы проверяем код, мы используем линтеры для обнаружения ошибок такого рода. Когда мы выполняем во время быстрого развития, у нас нет одинаковых стандартов. Непростительно спутать компилятор с линтером. Даже полиция стиля в Google не делает эту ошибку.
Трэвис Уилсон,

29

Для этого вы можете использовать простую «нулевую функцию», например:

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 не выдает предупреждения, а только ошибки, которые мешают компиляции.

Есть две причины отсутствия предупреждений. Во-первых, если стоит пожаловаться, стоит исправить в коде. (И если это не стоит исправлять, упоминать не стоит.) Во-вторых, компилятор генерирует предупреждения, побуждающие реализацию предупреждать о слабых случаях, которые могут вызвать компиляцию, и маскировать реальные ошибки, которые следует исправить.

Я не обязательно согласен с этим по разным причинам, в которые не стоит вдаваться. Это то, что есть, и вряд ли оно изменится в ближайшем будущем.

Для пакетов есть 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

Один угол, который не упомянут, это наборы инструментов, используемые для редактирования кода.

Использование Visual Studio код наряду с расширением из lukehoban под названием Goбудет сделать некоторые авто-волшебство для Вас. Расширение Go автоматически запускается gofmtи golintт. Д., А также удаляет и добавляет importзаписи . По крайней мере, эта часть теперь автоматическая.

Я признаю, что это не 100% решение вопроса, но, тем не менее, достаточно полезно.


8

В случае, если другим трудно понять это, я думаю, что это может помочь объяснить это очень просто. Если у вас есть переменная, которую вы не используете, например, функция, для которой вы закомментировали вызов (общий вариант использования):

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

Вы можете назначить бесполезную / пустую переменную функции, чтобы она больше не использовалась :

myFn := func () { }
_ = myFn
// myFn()
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.