16

Can anyone explain why 0's and 1's are printed and not anything else? Thank you!

func makeFunction(name string) func() {
    fmt.Println("00000")
    return func() {
        makeFunction2("abcef")
    }
}

func makeFunction2(name string) func() {
    fmt.Println("11111")
    return func() {
        makeFunction3("safsf")
    }
}

func makeFunction3(name string) func() {
    fmt.Println("33333")
    return func() {
        fmt.Printf("444444")
    }
}

func main() {
    f := makeFunction("hellooo")
    f()
}

Can anyone explain why 0's and 1's are printed and not anything else? Thank you!

2
  • 4
    Because you never call makeFunction3, its return value, and never print the name values? I'm not sure what you expect. Commented Jan 16, 2018 at 21:11
  • If you are going to call a chain of functions, with the same signature, I suggest take a look at implementing a FSM (Finite State Machine) in Go. This is not a full fledged FSM, but provides the essence, which makes these sort of tasks far cleaner. See this part by Rob Pike youtu.be/HxaD_trXwRE?t=14m7s Commented Jan 17, 2018 at 11:49

5 Answers 5

16

Let's follow the program flow:

  1. main starts.
  2. main calls makeFunction.
  3. makeFunction prints 00000, and returns an anonymous function.
  4. Back in main, we call the anonymous function returned by the previous call.
  5. The anonymous function calls makeFunction2.
  6. makeFunction2 prints 11111, and returns an anonymous function.
  7. main returns.

Because the return value is discarded after step 6 above, nothing else is printed.

Sign up to request clarification or add additional context in comments.

Comments

8

Let's look at your main:

Line 1

f := makeFunction("hellooo")
  • Side effect: printing "00000"
  • Return value: an anonymous function that executes makeFunction2("abcef"), assigned to the identifier f

Line 2

f()

which is equivalent to:

_ = f()
  • Side effect: printing "11111"
  • Return value: an anonymous function that executes makeFunction3("safsf"), discarded (you are not assigning the return value of f()).

makeFunction3 is never assigned to any identifier, and never called.

Comments

4

To prints the 3's, you have to call twice:

f()()

And to prints the 4's too, just do:

f()()()

Because ...

// prints "00000" and returns a function that if run
// will invoked `makeFunction2`
f := makeFunction("hello")

// `makeFunction2` is called, printing "11111" and returns 
// a function that if run will invoked `makeFunction3`
f1 := f()

// `makeFunction3` is called, printing "33333" and returns
// a function that if run will invoked `makeFunction4`
f2 := f1()

Test question, what does it print out if you do this?

f := makeFunction("Hello")()()
f()

This is known as currying or closure, but in your example you have not closed over any local value so the latter loses its meaning.

Comments

1

makeFunction only return the function makeFunction2. since this is not a recursive function. If you expecting to behave like recursive function, then you should change return func(){} to (return makeFunction2 or 3)

func makeFunction(name string) func() {
    fmt.Println("00000")
    return makeFunction2("abcef")
}

func makeFunction2(name string) func() {
    fmt.Println("11111")
    return makeFunction3("safsf")
}

func makeFunction3(name string) func() {
    fmt.Println("33333")
    return func() {
        fmt.Printf("444444")
    }
}

func main() {
    f := makeFunction("hellooo")
    f()
}

// Output: 
00000
11111
33333
444444

Comments

0

The Reason is it only returns the anonymous funtions.

package main

import "fmt"

func makeFunction(name string) func() {
    fmt.Println("00000")
    return func(){
        makeFunction2("abcef")()
    }
}

func makeFunction2(name string) func() {
    fmt.Println("11111")
    return func() {
        makeFunction3("safsf")()
    }
}

func makeFunction3(name string) func() {
    fmt.Println("33333")
    return func() {
        fmt.Printf("444444")
    }
}

func main() {
    f := makeFunction("hellooo")
    f()
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.