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”.