Bartłomiej Płotka, chief software engineer at Redhat and maintainer of projects such as Prometheus, asked a Go question on twitter with the following title.
Think about what the output will be.
Analyze the program
Narrow the scope and core focus to this piece of code. As follows.
In this last line of the closure (anonymous function), one might think that the program calls the done value returned by the function aaa to output the program, which should be:
|
|
This idea is wrong, the program does not work that way.
The reason is that return is actually an assignment statement. Combined with the program, you can see that the first return value of function bbb is the done argument.
As follows.
|
|
That is, after the function bbb executes the return statement at the end of the program, it will assign a value to the return variable done, which naturally will not be set by the function aaa.
This is a key point.
The process
What is the output of this program?
He will keep recursively outputting “bbb: surprise!” until the stack overflows , causing the program to run with errors and eventually abort!
Here comes the confusion, how come there is an additional recursion?
Let’s look at the program again.
Essentially, after the function bbb is executed, the variable done has become a recursive function.
The recursive process is that the function bbb calls the variable done, which outputs the bbb: surprise! string, and then calls the variable done. The variable done is in turn this closure (anonymous function), thus enabling constant recursive calls and output.
The end result is as follows.
|
|
That is, the correct answer is: D. The program eventually runs in error.
If we remove the return parameter naming from this function, we can avoid this problem. As follows.
The output is “bbb: surprise!aaa: done”.