Co to jest „_” (podkreślenie przecinek) w deklaracji Go?

100

I wydaje mi się, że nie rozumiem tego rodzaju deklaracji zmiennej:

_, prs := m["example"]

Co dokładnie „ _,” robi i dlaczego zamiast tego zadeklarowali taką zmienną

prs := m["example"]

(Znalazłem to jako część Go by Example: Maps )

Kansuler
źródło
3
W przypadku pytań językowych w przyszłości zapoznaj się najpierw ze specyfikacją . Powinien odpowiedzieć na wszystkie Twoje pytania.
fuz
Jako komentarz: prsprawdopodobnie oznacza „obecny”. Kod w przykładzie jest sprawdzanie pod kątem obecności lub braku wpisu do "example"w mmapie.
dyoo
6
@FUZxxl Tak, zajrzałem tam wcześniej, ale ponieważ nie znałem nazwy funkcji, nie znalazłem jej. Uważam również, że oficjalne specyfikacje języków programowania nie są zbyt pedagogiczne i raczej uczą się na przykładach.
Kansuler,
@dyoo Kiedy już miałem wyjaśnienie poniżej, zrozumiałem, jakie jest jego znaczenie, ale warto zauważyć, że ktoś inny ma to samo pytanie!
Kansuler,
8
@FUZxxl: Nie wiem. Większość pytań zadanych w SO prawdopodobnie ma gdzieś dostępne odpowiedzi . Istnieje pewien próg, poniżej którego prawdopodobnie nie powinno się zadawać pytania, ale nie sądzę, aby to pytanie znajdowało się poniżej.
thb

Odpowiedzi:

121

Pozwala to uniknąć konieczności deklarowania wszystkich zmiennych dla zwracanych wartości.
Nazywa się to pustym identyfikatorem .

Jak w:

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

( drugi _przypadek użycia dotyczy importu )

Ponieważ odrzuca wartość zwracaną, jest to przydatne, gdy chcesz sprawdzić tylko jedną ze zwracanych wartości, jak w sekcji „ Jak sprawdzić istnienie klucza na mapie? ” Pokazanej w sekcji „ Efektywne przejście, mapa ”:

_, present := timeZone[tz]

Aby przetestować obecność na mapie bez martwienia się o rzeczywistą wartość, możesz użyć pustego identyfikatora, prostego podkreślenia ( _).
Pustemu identyfikatorowi można przypisać lub zadeklarować dowolną wartość dowolnego typu, z wartością odrzuconą w nieszkodliwy sposób.
Aby sprawdzić obecność na mapie, użyj pustego identyfikatora zamiast zwykłej zmiennej wartości.

Jak dodaje Jsor w komentarzach :

„ogólnie przyjętym standardem” jest wywołanie zmiennych testowych członkostwa „ok” (to samo dotyczy sprawdzania, czy odczyt kanału był prawidłowy, czy nie)

To pozwala połączyć to z testem:

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

Znajdziesz go również w pętli:

Jeśli potrzebujesz tylko drugiego elementu z zakresu (wartości), użyj pustego identyfikatora, podkreślenia, aby odrzucić pierwszy:

sum := 0
for _, value := range array {
    sum += value
}
VonC
źródło
Dzięki za dobry przykład. Zrozumienie tej koncepcji zajęło mi trochę czasu, ale teraz rozumiem!
Kansuler
Zauważ, że „ogólnie akceptowanym standardem” IME jest wywoływanie zmiennych testowych członkostwa „ok” (to samo dotyczy sprawdzania, czy odczyt kanału był prawidłowy, czy nie).
LinearZoetrope
1
@Jsor Zgadzam się. W odpowiedzi zawarłem twój komentarz dla większej czytelności i dodałem kilka dodatkowych przykładów.
VonC
64

Kompilator Go nie pozwala na tworzenie zmiennych, których nigdy nie używasz.

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

Powyższy kod zwróci komunikat o błędzie „zadeklarowałem i nie używam”.

Ponieważ nie używamy i wewnątrz naszej pętli, musimy to zmienić na to:

for _, value := range x {
   total += value
}
Juni Brosas
źródło
13
Twoje pierwsze zdanie było ważne, aby zrozumieć powód, dla którego istnieje _ jako pusty identyfikator.
Tarik
4

_jest pustym identyfikatorem. Oznacza to, że wartość, którą należy przypisać, jest odrzucana.

Tutaj wartość exampleklucza jest odrzucana. Druga linia kodu odrzuciłaby wartość logiczną obecności i zapisałaby wartość w prs.
Aby sprawdzić tylko obecność na mapie, możesz odrzucić wartość. Można to wykorzystać do użycia mapy jako zestawu.

ThinkChaos
źródło
3

Pustego identyfikatora można użyć, gdy składnia wymaga nazwy zmiennej, ale logika programu nie wymaga, na przykład w celu odrzucenia niechcianego indeksu pętli, gdy potrzebujemy tylko wartości elementu.

Fragment:

Język programowania Go (seria Addison-Wesley Professional Computing)

Brian W. Kernighan

Ten materiał może być chroniony prawem autorskim.

koopertrooper
źródło
2

Nazywa się to pustym identyfikatorem i pomaga w przypadkach, gdy chcesz odrzucić wartość, która ma zostać zwrócona i nie odwoływać się do niej

Niektóre miejsca, w których go używamy:

  • Funkcja zwraca wartość i nie zamierzasz jej używać w przyszłości
  • Chcesz iterować i potrzebujesz wartości i, której nie będziesz używać
Anagha
źródło
1

Zasadniczo _,znany jako pusty identyfikator. W GO nie możemy mieć zmiennych, które nie są używane.

Na przykład podczas iteracji po tablicy, jeśli używasz value: = range , nie chcesz, aby wartość i była iterowana. Ale jeśli pominiesz wartość i, zwróci błąd. Ale jeśli zadeklarujesz i i nie użyłeś go, również zwróci błąd.

Dlatego jest to miejsce, z którego musimy skorzystać _,.

Jest również używany, gdy nie chcesz w przyszłości zwracać wartości funkcji.

Kaveen Hiacinth
źródło
1

Świetnym przypadkiem użycia nieużywanej zmiennej jest sytuacja, w której potrzebujesz tylko częściowego wyniku. W poniższym przykładzie wystarczy wydrukować wartość (stan populacji).

package main
import (
    "fmt"
)
func main() {
          statePopulations := map[string]int{
          "California": 39250017,
          "Texas":      27862596,
          "Florida":    20612439,
          }
          for _, v := range statePopulations {
          fmt.Println(v)
    }
}
monkrus
źródło
0

Niewykorzystana zmienna nie jest dozwolona w Golangu

Jeśli pochodzisz z innych języków programowania, może to być trudne przyzwyczajenie się do tego. Ale to skutkuje bardziej przejrzystym kodem. Więc używając a, _mówimy, że wiemy, że jest tam zmienna, ale nie chcemy jej używać i mówimy kompilatorowi, że mi na to nie narzeka. :)

Krishnadas PC
źródło