Что означает «_» (подчеркивающая запятая) в объявлении Go?


100

И я не могу понять такое объявление переменной:

_, prs := m["example"]

Что именно " _," делает и почему они объявили такую ​​переменную вместо

prs := m["example"]

(Я нашел его как часть Go by Example: Maps )


3
Если в будущем возникнут вопросы о языке, пожалуйста, сначала ознакомьтесь со спецификацией . Он должен ответить на все ваши вопросы.
fuz 04

В качестве комментария: prsвероятно, означает «настоящее». Код в вашем примере проверяет наличие или отсутствие записи для "example"на mкарте.
dyoo 05

6
@FUZxxl Да, я заглядывал туда раньше, но, поскольку я не знал названия функции, я не нашел ее. Кроме того, я считаю, что официальные спецификации языков программирования не очень педагогичны и скорее учатся на примере.
Kansuler 05

@dyoo Как только у меня появилось объяснение ниже, я понял, что это означает, но стоит отметить, если у кого-то еще есть такой же вопрос!
Kansuler

8
@FUZxxl: не знаю. На большинство вопросов, заданных в SO, вероятно, есть ответы где-нибудь. Существует некоторый порог, ниже которого вопрос, вероятно, не следует задавать, но я не думаю, что этот вопрос ниже этого уровня.
чт,

Ответы:


121

Это позволяет избежать объявления всех переменных для возвращаемых значений.
Это называется пустым идентификатором .

Как в:

_, y, _ := coord(p)  // coord() returns three values; only interested in y coordinate

( другой _вариант использования - импорт )

Поскольку он отбрасывает возвращаемое значение, это полезно, когда вы хотите проверить только одно из возвращенных значений, как в разделе « Как проверить наличие ключа на карте? » В разделе « Эффективный переход, карта »:

_, present := timeZone[tz]

Чтобы проверить присутствие на карте, не беспокоясь о фактическом значении, вы можете использовать пустой идентификатор, простой символ подчеркивания ( _).
Пустой идентификатор может быть назначен или объявлен с любым значением любого типа, при этом значение отбрасывается безвредно.
Для проверки присутствия на карте используйте пустой идентификатор вместо обычной переменной для значения.

Как добавляет Jsor в комментариях :

«общепринятый стандарт» - это называть переменные теста принадлежности «ок» (то же самое для проверки, было ли чтение канала действительным или нет)

Это позволяет комбинировать его с тестом:

if _, err := os.Stat(path); os.IsNotExist(err) {
    fmt.Printf("%s does not exist\n", path)
}

Вы также найдете это в цикле:

Если вам нужен только второй элемент в диапазоне (значение), используйте пустой идентификатор, подчеркивание, чтобы отбросить первый:

sum := 0
for _, value := range array {
    sum += value
}

Спасибо за хороший пример. Мне потребовалось некоторое время, чтобы понять концепцию, но теперь я понимаю!
Kansuler

Обратите внимание, что «общепринятый стандарт» IME заключается в том, чтобы вызвать переменные теста членства «ok» (то же самое для проверки, было ли чтение канала действительным или нет).
LinearZoetrope 04

1
@Jsor Я согласен. Я включил ваш комментарий в ответ для большей наглядности и добавил несколько дополнительных примеров.
VonC

64

Компилятор Go не позволит вам создавать переменные, которые вы никогда не используете.

for i, value := range x {
   total += value
}

Приведенный выше код вернет сообщение об ошибке «Я объявлен и не используется».

Поскольку мы не используем i внутри нашего цикла, нам нужно изменить его на это:

for _, value := range x {
   total += value
}

13
Ваше первое предложение было важно для понимания причины, по которой _ является пустым идентификатором.
Тарик

4

_- пустой идентификатор. Это означает, что значение, которое ему следует присвоить, отбрасывается.

Здесь exampleотбрасывается значение ключа. Вторая строка кода отбрасывает логическое значение присутствия и сохраняет значение в prs.
Таким образом, чтобы только проверить наличие на карте, вы можете отбросить значение. Это можно использовать для использования карты как набора.


3

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

Выдержка из:

Язык программирования Go (серия профессиональных вычислений Аддисон-Уэсли)

Брайан В. Керниган

Этот материал может быть защищен авторским правом.


2

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

Некоторые места, где мы его используем:

  • Функция возвращает значение, и вы не собираетесь использовать его в будущем.
  • Вы хотите выполнить итерацию, и вам нужно значение i, которое вы не будете использовать

1

Обычно это _,называется пустым идентификатором. В GO у нас не может быть переменных, которые не используются.

Например, при итерации по массиву, если вы используете value: = range, вам не нужно значение i для итерации. Но если вы опустите значение i, он вернет ошибку. Но если вы объявите i и не использовали его, он также вернет ошибку.

Следовательно, это то место, где мы должны использовать _,.

Также он используется, когда вы не хотите, чтобы функция возвращала значение в будущем.


1

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

package main
import (
    "fmt"
)
func main() {
          statePopulations := map[string]int{
          "California": 39250017,
          "Texas":      27862596,
          "Florida":    20612439,
          }
          for _, v := range statePopulations {
          fmt.Println(v)
    }
}

0

Неиспользуемая переменная в Голанге запрещена.

Если вы переходили с других языков программирования, вам было бы немного сложно привыкнуть к этому. Но это приводит к более чистому коду. Таким образом, используя a, _мы говорим, что знаем, что есть переменная, но не хотим ее использовать, и сообщаем компилятору, что не жалуется мне на это. :)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.