Odniesienia
The Go Programming Language Specification
Function types
typ funkcji oznacza zbiór wszystkich funkcji, z tych samych typem i wynikowych.
FunctionType = "func" Signature .
Signature = Parameters [ Result ] .
Result = Parameters | Type .
Parameters = "(" [ ParameterList [ "," ] ] ")" .
ParameterList = ParameterDecl { "," ParameterDecl } .
ParameterDecl = [ IdentifierList ] [ "..." ] Type .
Function declarations
Oświadczenie funkcja wiąże identyfikator, nazwę funkcji, do funkcji.
FunctionDecl = "func" FunctionName Signature [ Body ] .
FunctionName = identifier .
Body = Block .
Function literals
Funkcja dosłownym oznacza anonimową funkcję. Składa się ze specyfikacji typu funkcji i treści funkcji.
FunctionLit = FunctionType Body .
literały funkcyjne są zamknięcia: mogą one odnosić się do zmiennych zdefiniowanych w otaczającą funkcyjnego. Zmienne te są następnie dzielone między funkcję otaczającą i literalną funkcji, i zachowują się tak długo, jak są dostępne.
Literał funkcji można przypisać do zmiennej lub wywołać bezpośrednio.
Calls
Biorąc wyrazem f
funkcji typu F
,
f(a1, a2, … an)
rozmowy f
z argumentami a1, a2, … an
.
W wywołaniu funkcji wartość funkcji i argumenty są obliczane w zwykłej kolejności według . Po ich ocenie parametry wywołania są przekazywane wartości do funkcji, a wywoływana funkcja zaczyna się od wykonania . Parametry zwracane funkcji są przekazywane z powrotem do wywołującej funkcji o wartości , gdy funkcja zwraca.
Defer statements
A „defer
” oświadczenie wywołuje funkcję, której wykonanie jest odroczone do momentu okolicznych powraca funkcyjnych.
DeferStmt = "defer" Expression .
Wyrażenie musi być funkcją lub wywołaniem metody. Za każdym razem, gdy wykonywana jest instrukcja "defer
", wartość funkcji i parametry połączenia są obliczane jak zwykle i zapisywane od nowa, ale faktyczna funkcja nie jest wywoływana.Zamiast tego, odroczone połączenia są wykonywane w kolejności LIFO bezpośrednio przed powrotem funkcji otaczającej, po zwróceniu wartości , jeśli takie istnieją, ale zanim zostaną zwrócone do dzwoniącego.
Ponieważ wciąż nie masz pojęcia, oto kolejna próba udzielenia odpowiedzi na Twoje pytanie.
W kontekście twojego pytania, ()
jest operatorem wywoływania funkcji.
Na przykład, funkcja dosłownym
func(i int) int { return 42 * i }
oznacza anonimową funkcję.
Funkcja dosłownym następnie ()
funkcji operatora wywołania
func(i int) int { return 42 * i }(7)
oznacza anonimową funkcję, która jest następnie wywoływany bezpośrednio.
Zwykle w wywołaniu funkcji wartość funkcji i argumenty są obliczane w zwykłej kolejności. Po ich ocenie parametry wywołania są przekazywane wartości do funkcji, a wywoływana funkcja rozpoczyna wykonywanie. Parametry zwracane przez funkcję są przekazywane z powrotem do funkcji wywołującej, gdy funkcja zwraca.
Jednak wywołanie funkcji za pomocą polecenia odroczenia jest przypadkiem specjalnym. Za każdym razem, gdy wykonywana jest instrukcja "odroczenia", wartość funkcji i parametry połączenia są obliczane jak zwykle i zapisywane od nowa, ale faktyczna funkcja nie jest wywoływana. Zamiast tego, odroczone połączenia są wykonywane w kolejności LIFO bezpośrednio przed powrotem funkcji otaczającej, po zwróceniu wartości, jeśli jakiekolwiek, zostały ocenione, ale zanim zostaną zwrócone do osoby dzwoniącej.
Wyrażenie instrukcji odroczenia musi być wywołaniem funkcji lub metody, które jest wywoływane bezpośrednio, a nie tylko literałem funkcji lub metody, który nie jest wywoływany bezpośrednio. W związku z tym po funkcji lub metodzie cyfrowej musi następować operator wywołania funkcji ()
, aby wyrażenie odroczenia było funkcją lub wywołaniem metody.
Oświadczenie Defer
defer func(i int) int { return 42 * i }(7)
jest prawidłowy.
Oświadczenie Defer
defer func(i int) int { return 42 * i }
jest nieprawidłowy: syntax error: argument to go/defer must be function call
.
Dostałem twój punkt, więc w 'func (ch chan int) {ch <- ACK} (replyChan)', 'func (ch chan int) {ch <- ACK}' oznacza definicję zamknięcia, '(replyChan) 'oznacza" wykonaj to zamknięcie za pomocą parametru 'replyChan'". –
Kolejne pytanie z twojego ostatniego przykładu: jaka jest różnica między "w momencie, kiedy zamknięcie się wykonuje" i "w momencie, kiedy została wykonana instrukcja odroczenia"? Jeśli mam 'return' po' for {} ', oba te 2' odroczenia 'powinny zostać wykonane przed' return' w tym samym czasie, czyż nie? –
@ReckHou: Uruchom http://play.golang.org/p/Orm-0EaBY6 i spójrz na dane wyjściowe – zzzz