kunrazor
kunrazor

Reputation: 361

Golang returning functions

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!

Upvotes: 16

Views: 34984

Answers (5)

0example.com
0example.com

Reputation: 307

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()
}

Upvotes: 0

Adriel Artiza
Adriel Artiza

Reputation: 337

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

Upvotes: 1

Pandemonium
Pandemonium

Reputation: 8390

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.

Upvotes: 4

Pierre Prinetti
Pierre Prinetti

Reputation: 9622

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.

Upvotes: 8

Adrian
Adrian

Reputation: 46442

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.

Upvotes: 16

Related Questions