在《围棋之旅》中写道:
延迟调用的参数将立即求值,但是直到周围的函数返回后,函数调用才会执行。
我很难理解报价的第一部分。什么叫立即?
func def(s string) func() {
fmt.Println("tier up")
fmt.Println(s)
return func(){ fmt.Println("clean up") }
}
func main() {
defer def("defered line")()
fmt.Println("main")
}
//Output:
//tier up
//defered line
//main
//clean up
Run Code Online (Sandbox Code Playgroud)
https://play.golang.org/p/Av3mAEXxA4R
在这里推迟什么,立即评估什么?
要了解延迟和评估的工作原理,首先让我们看一下Spec:defer语句:
每次“延迟”执行语句,函数值和参数来调用被评价像往常一样,重新保存,但不会被调用的实际功能。
函数值(其调用被延迟)及其参数均被评估。但是尚未调用延期函数。
让我们以小步骤迭代到您的示例:
defer f("a")
Run Code Online (Sandbox Code Playgroud)
在这种情况下,将评估函数值(将为f),并对参数进行评估,该参数是一个常量,因此将为"a"。
下一步:
defer f(g("a"))
Run Code Online (Sandbox Code Playgroud)
在这种情况下,将对函数值进行评估(将为f),并对参数进行评估,这g将使用进行调用"a"(因为g返回值是的参数f)。
下一步:
defer f()()
Run Code Online (Sandbox Code Playgroud)
如果该f函数返回一个函数,则此方法有效。函数值将被评估(这意味着f将被调用!),但其返回值将不被调用,即被推迟。
defer f(g())()
Run Code Online (Sandbox Code Playgroud)
在这种情况下,延迟函数是的返回值f,因此f必须调用评估延迟函数值,并且必须先调用此函数g。的返回值f将被延迟(不调用)。
回到您的示例:
defer def("defered line")()
Run Code Online (Sandbox Code Playgroud)
计算函数值,它是的返回值def,因此def称为。的返回值def将被推迟。它的参数已评估,但实际上没有参数。
因此,从逻辑上讲这是发生的情况:
def 函数必须被调用,这要求:
def评估的参数是一个常量:defered line"如果我们布置以上结构,则会依次发生以下情况:
def评估参数:这是一个常数"defered line"def被称为打印tier up及其参数:defered linedef是不叫,这是什么推迟。main打印:mainmain返回,因此现在调用延迟函数。延迟功能打印clean up| 归档时间: |
|
| 查看次数: |
416 次 |
| 最近记录: |