使用闭包在Go中编写下一个置换,我的代码有什么问题

I have written a function "iterPermutation" which uses closure. I want to return array and boolean from the closure which I could not do. So tried only array but it still gives an error

cannot use func literal (type func() []int) as type []int in return argument

I want to use iterPermutation like

a := []int{0,1,2,3,4}
nextPermutation, exists := iterPermutation(a)
for exists {
    nextPermutation()
}

func iterPermutation(a []int) []int {
    return func() []int {
        i := len(a) - 2

        for i >= 0 && a[i+1] <= a[i] {
            i--
        }
        if i < 0 {
            return a
        }

        j := len(a) - 1
        for j >= 0 && a[j] <= a[i] {
            j--
        }

        a[i], a[j] = a[j], a[i]

        for k, l := i, len(a)-1; k < l; k, l = k+1, l-1 {
            a[k], a[l] = a[l], a[k]
        }
        return a
    }
}

Golang spec for Return statements described:

The return value or values may be explicitly listed in the "return" statement. Each expression must be single-valued and assignable to the corresponding element of the function's result type.

The function called for permutation should contains two values in return one for the array and another for the boolean. Since you are assigning two variables from the function return:

a := []int{0,1,2,3,4}
nextPermutation, exists := iterPermutation(a) // it should return two values one for nextPermutation which is an array and other is exists which might be a boolean value.
for exists {
    nextPermutation()
}

For below error:

"cannot use func literal (type func() []int) as type []int in return argument"

you are returning func() literal enclosed inside the closure function of permutation along with boolean value, so change the return type as:

package main

func main(){
    a := []int{0,1,2,3,4}
    nextPermutation, _ := iterPermutation(a)
        nextPermutation()
}

func iterPermutation(a []int) ((func() []int), bool) { // return both values
    return func() []int {
        i := len(a) - 2

        for i >= 0 && a[i+1] <= a[i] {
            i--
        }
        if i < 0 {
            return a
        }

        j := len(a) - 1
        for j >= 0 && a[j] <= a[i] {
            j--
        }

        a[i], a[j] = a[j], a[i]

        for k, l := i, len(a)-1; k < l; k, l = k+1, l-1 {
            a[k], a[l] = a[l], a[k]
        }
        return a
    }, true // add boolean value to return from the function.
}

Working answer on Playground

I'm going to ignore the "permutation" logic inside your closure and focus on couple of concepts that you need to be aware of so it would work like you've planned to with your code. Correct me if I'm wrong, but you want to get array of item from your closure until exists is false, right?

First of all, to have nextPermutation, exists := iterPermutation(a) compile properly, iterPermutation needs to return two values like so:

func iterPermutation(a []int) (func() []int, bool) {
   exists := true
   return func() []int {
      //rest of your code
      if i < 0 {
        exists = false
        return a
      }
      //rest of your code
   }, exists
} 

Next problem you face is the fact that, with the above approach, you will have with the exists value. Since you are returning a value for exists, any change to exists will not be propagated beyond the scope of iterPermutation. You can fix this problem by returning a pointer. This is one way of implementing it:

a := []int{0,1,2,3,4}
nextPermutation, check := iterPermutation(a)

while check.Exists {
   nextPermutation()
}

type Check struct {
    Exists bool 
}

func iterPermutation(a []int) (func() []int, *Check) {
check:= &Check{
          Exists: true,
}   
return func() []int {
        i := len(a) - 2

        for i >= 0 && a[i+1] <= a[i] {
            i--
        }
        if i < 0 {
        check.Exists = false //this is put here as an example
            return a
        }

        j := len(a) - 1
        for j >= 0 && a[j] <= a[i] {
            j--
        }

        a[i], a[j] = a[j], a[i]

        for k, l := i, len(a)-1; k < l; k, l = k+1, l-1 {
            a[k], a[l] = a[l], a[k]
        }
        return a
    }, check
}

When you return a pointer of Check type, any change to it in the iterPermutation or in your closure is visible outside of these as well, since you are accessing a memory reference.