jiaweizhang
jiaweizhang

Reputation: 819

Go closure with naked return

I am playing around with Go and am trying to implement a fibonacci function that returns a closure that returns fibonacci numbers. The problem can be found in the go tool tour. Here is a closure implementation that uses a regular (non-naked) return:

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    a := 0
    b := 1
    return func() int {
        t := a + b
        a = b
        b = t
        return b
    }
}

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}

The function correctly returns the following:

1
2
3
5
8
13
21
34
55
89

I tried writing the fibonacci function differently by trying to use a naked return within the closure function, but it produces an error:

./compile20.go:9:7: b declared and not used

Here is the code that generates the error

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    a := 0
    b := 1
    return func() (b int) {
        t := a + b
        a = b
        b = t
        return
    }
}

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}

Anybody know how the variable b is not being used? b is obviously used in the first line of the closure function (t := a + b).

Upvotes: 2

Views: 745

Answers (1)

Arie Xiao
Arie Xiao

Reputation: 14082

Variables defined in the return segment shadow the variable with the same name in the outer scope. Inside your returned function, b refers to the one defined in the return value.

You can remove the first declaration (and initialization) of b and the program passes the check, although the logic is not right.

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    a := 0
    b := 1 // declare a variable b and initialize with 1
    return func() (b int) { // declare a variable b with default initialization
        t := a + b // b refers to the variable defined in the return value
        a = b
        b = t
        return
    }
}

Upvotes: 2

Related Questions