2016-12-03 16 views
6

Piszę parser w programie Go for Go, a aby go przetestować, pobrałem kilka plików z projektów Github.
W https://github.com/andlabs/ui wpadłem do pliku zawierającego ten kawałek kodu:Czy nienazwane argumenty są w programie Go?

func moveLabel(*Button) { 
    from := movingCurrent 
    to := 0 
    if from == 0 { 
     to = 1 
    } 
    movingBoxes[from].Delete(0) 
    movingBoxes[to].Append(movingLabel, false) 
    movingCurrent = to 
} 

mylić mnie trochę, aby zobaczyć wskaźnik do Button bez nazwy jako argumentu funkcji, co sprawia, że ​​niemożliwe jest odniesienie od wewnątrz funkcja.
Jednak wydaje się, że jest poprawna pod względem składni, ponieważ kompilator nie narzeka.
Jaki jest cel argumentów funkcji nie zarejestrowanych w programie Go?

+0

Dodano więcej szczegółów, wyjaśnienie (na podstawie specyfikacji) i linki do odpowiedzi. – icza

Odpowiedz

8

Nienazwane parametry są całkowicie poprawne. Parameter declaration z spec:

ParameterDecl = [ IdentifierList ] [ "..." ] Type . 

Jak widać, IdentifierList (nazwa identyfikatora lub nazwy) jest w nawiasach kwadratowych, co oznacza, że ​​to opcjonalnie. Wymagany jest tylko Type.

Powodem tego jest fakt, że nazwy nie są tak naprawdę ważne dla kogoś wywołującego metodę lub funkcję. Liczy się rodzaj parametrów i ich kolejność. Jest to szczegółowe w tej odpowiedzi: Getting method parameter names in Golang

Na ogół podajesz zmienne i parametry, aby można było do nich odnosić się.

Jeśli czegoś nie nazywasz, to dlatego, że nie chcesz się do niego odwoływać.

Pytanie powinno zatem brzmieć: Dlaczego nie chcę odwoływać się do parametru?

Na przykład, ponieważ parametr „jest tam” (jest on przekazywany), ale nie trzeba go, że nie chcesz z niego korzystać. Po co miałoby być, gdybym go nie potrzebował?

Ponieważ ktoś lub coś dyktuje, aby uzyskać określone parametry. Na przykład chcesz zaimplementować interfejs lub chcesz przekazać wartość funkcji, której podpis jest zdefiniowany przez oczekiwany typ funkcji.

Zobaczmy przykład. Mamy następujące MyWriter interfejs:

type MyWriter interface { 
    Write(p []byte) error 
} 

uproszczonej io.Writer który zwraca tylko błąd, ale nie zgłasza liczbę zapisanych bajtów. Jeśli tylko chcesz, aby zapewnić realizację którego właśnie odrzuca dane (podobne do ioutil.Discard), a następnie realizacja nie korzysta (nie trzeba używać) swój argument:

type DiscardWriter struct{} 

func (DiscardWriter) Write([]byte) error { return nil } 

i to wszystko: my don” t używaj odbiornika, nie używamy argumentu. Oba mogą być bez nazwy. A implementacja robi dokładnie to, co powinna.

W ten sposób (przy użyciu parametrów bez nazwy) również dokumenty, że wartość nie jest używana/odniesione.

Innym powodem może być zapewnienie zgodności z do przodu. Jeśli zwolnisz bibliotekę, nie możesz zmienić ani rozszerzyć listy parametrów bez łamania wstecznej kompatybilności (aw Go nie ma przeciążania funkcji: jeśli chcesz 2 warianty z różnymi parametrami, ich nazwy również muszą być różne). Możesz zadeklarować wcześniej wyeksportowaną funkcję lub metodę z dodatkowymi parametrami, ale ponieważ nie używasz ich jeszcze, możesz pozostawić ich bez nazwy. Przykład tego jest szczegółowo opisany w tej odpowiedzi: Why does Go allow compilation of unused function parameters?

Należy tutaj zwrócić uwagę na to, że nie można łączyć parametrów nazwanych i nienazwanych. Jeśli wymieniasz niektóre, musisz wymienić wszystkie. Jeśli nie potrzebujesz wszystkich, można użyć blank identifier jak w poniższym przykładzie:

prosty serwer WWW, który reaguje z tekstem do wszystkich żądań "Hello":

http.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) { 
    io.WriteString(w, "Hello") 
}) 
panic(http.ListenAndServe(":8080", nil)) 

Funkcja obsługi odesłanie "Hello" tekst używa tylko pisarza odpowiedzi w, ale nie struktury żądania, więc pusty identyfikator jest używany jako jego nazwa.

Innym powiązane pytanie:

Why must we declare a variable name when adding a method to a struct in Golang?

również nieco pokrewny, lecz dotyczące używając/nazewnictwa zwracane wartości:

Return map like 'ok' in Golang on normal functions

Powiązane problemy