参考
Go 编程语言规范
函数类型
函数类型表示具有相同参数和结果类型的所有函数的集合。
FunctionType = "func" Signature .
Signature = Parameters [ Result ] .
Result = Parameters | Type .
Parameters = "(" [ ParameterList [ "," ] ] ")" .
ParameterList = ParameterDecl { "," ParameterDecl } .
ParameterDecl = [ IdentifierList ] [ "..." ] Type .
函数声明
函数声明将标识符(函数名称)绑定到函数。
FunctionDecl = "func" FunctionName Signature [ Body ] .
FunctionName = identifier .
Body = Block .
函数字面量
函数字面量表示匿名函数。它由函数类型的规范和函数体组成。
FunctionLit = FunctionType Body .
函数字面量是闭包:它们可以引用在周围函数中定义的变量。然后,这些变量在周围的函数和函数字面量之间共享,只要它们可以访问,它们就会继续存在。
函数文字可以分配给变量或直接调用。
来电
f
给定函数类型的表达式F
,
f(a1, a2, … an)
f
带参数的调用a1, a2, … an
。
在函数调用中,函数值和参数按通常的顺序计算。在它们被评估之后,调用的参数按值传递给函数,被调用的函数开始执行。函数的返回参数在函数返回时按值传回调用函数。
延迟语句
" defer
" 语句调用一个函数,该函数的执行推迟到周围函数返回的那一刻。
DeferStmt = "defer" Expression .
表达式必须是函数或方法调用。每次defer
执行 " " 语句时,调用的函数值和参数都会像往常一样进行评估并重新保存,但不会调用实际函数。相反,延迟调用在周围函数返回之前立即按 LIFO 顺序执行,在返回值(如果有的话)被评估之后,但在它们返回给调用者之前。
由于您仍然感到困惑,因此这是另一种尝试为您的问题提供答案。
在您的问题的上下文中,()
是函数调用运算符。
例如,函数字面量
func(i int) int { return 42 * i }
表示匿名函数。
函数字面量后跟()
函数调用运算符
func(i int) int { return 42 * i }(7)
表示一个匿名函数,然后直接调用它。
通常,在函数调用中,函数值和参数按通常的顺序计算。在它们被评估之后,调用的参数按值传递给函数,被调用的函数开始执行。函数的返回参数在函数返回时按值传回调用函数。
但是,通过 defer 语句调用函数是一种特殊情况。每次执行“defer”语句时,调用的函数值和参数都会像往常一样进行评估并重新保存,但不会调用实际函数。相反,延迟调用在周围函数返回之前立即按 LIFO 顺序执行,在返回值(如果有的话)被评估之后,但在它们返回给调用者之前。
defer 语句表达式必须是直接调用的函数或方法调用,而不仅仅是不直接调用的函数或方法字面量。因此,函数或方法字面量后面需要跟()
函数调用运算符,这样defer语句表达式就是函数或方法调用。
延迟声明
defer func(i int) int { return 42 * i }(7)
已验证。
延迟声明
defer func(i int) int { return 42 * i }
无效:syntax error: argument to go/defer must be function call
。