The question
The quiz shows two functions and asks what the code prints:
func greetCoder() {
fmt.Println("Hello!")
fmt.Println("Let's code!")
}
func mainFunction() {
greetCoder()
greetCoder()
}
Four options are offered, and you answer with a letter:
- A:
Hello!,Let's code!,Hello!,Let's code!(each message pair twice); - B:
Hello!,Hello!,Let's code!,Let's code!; - C:
Hello!,Let's code!(once); - D: the pair three times.
Tracing the code
The way to answer a quiz like this is to follow the program the way Go does, one step at a time.
- The definition of
greetCoderprints nothing. It only tells Go what the namegreetCodermeans. - The program runs
mainFunction. Its first statement isgreetCoder(), a call. Go jumps into the body and runs it from top to bottom:Hello!, thenLet's code!. The body ends, and Go returns to the line after the call. - The second statement is another call. The body runs again from its first line, printing
Hello!andLet's code!once more.
The full output is:
Hello!
Let's code!
Hello!
Let's code!
That matches option A.
Why the other options are wrong
- B groups the lines by message. That would happen only if the program ran the first
Printlntwice and then the second one twice. A call runs the entire body each time, so the pair stays together. - C assumes one run of the body. There are two calls, so the body runs two times.
- D counts three runs. The definition is not a run, and there are only two calls.
A variation to try on paper
Suppose a third function wraps the two calls, and a program prints a line before and after it:
func twice() {
greetCoder()
greetCoder()
}
func main() {
fmt.Println("start")
twice()
fmt.Println("end")
}
The output is start, then the four lines from the two greetings, then end. Each call finishes completely before the line after it runs, so the statements in main keep their written order, with the whole body of the called function placed where its call stands. Tracing this way works for any amount of nesting.
The solution in Go
The answer is a string variable named answer:
var answer string = "A"
/* Explanation:
In the first 4 lines of code we only define the function, so no "fmt.Println()" statement will actually get executed.
Then, inside the main function, we call the function for the first time, so all the statements inside the function body will get executed from top to bottom.
So, the first function call will print "Hello!", then it will print "Let's code!" on two separate lines, and then this function call ends.
The output so far is:
Hello!
Let's code!
Then we call the function for the second time, and again all the statements inside the function body will get executed from top to bottom.
So the second function call will again print "Hello!", then it will print "Let's code!" on two separate lines, and then the function call ends.
So the output is:
Hello!
Let's code!
Hello!
Let's code!
*/
About the Go in that line:
var answer string = "A"declares a variable namedanswer, gives it the typestringand sets it to the text"A". The quotes are required:Awithout them would be taken as the name of some other variable.- The type can be left out of the declaration, as in
var answer = "A", and Go infersstring. Inside a function you could also writeanswer := "A". The lesson uses the long form. - The explanation sits between
/*and*/. Go skips everything inside such a block comment.
Common mistakes
- Thinking a call runs one line. A call runs the whole body, every statement, in order.
- Counting the definition as a run. Only a call, which is the name followed by parentheses, makes the body run.
- Forgetting the second call. Count the calls first. The number of calls is the number of times the body runs.
- Answering with the output instead of the letter.
answerholds just"A".
Key takeaways
- Each call runs the full body, from the first line to the last.
- Calling a function twice repeats its output twice, in the same order.
- Declaring a function never prints anything by itself.