编写深度为d的嵌套迭代器

How to realize a nested iterator that takes a depth argument. A simple iterator would be when depth = 1. it is a simple iterator which runs like a simple for loop.

func Iter () chan int {
    ch := make(chan int);
    go func () {
        for i := 1; i < 60; i++ {
            ch <- i
        }
        close(ch)
    } ();
    return ch
}

Output is 1,2,3...59

For depth = 2 Output would be "1,1" "1,2" ... "1,59" "2,1" ... "59,59"

For depth = 3 Output would be "1,1,1" ... "59,59,59"

I want to avoid a nested for loop. What is the solution here ?

I don't know if it is possible to avoid nested loops, but one solution is to use a pipeline of channels. For example:

const ITER_N = 60

// ----------------

func _goFunc1(out chan string) {
    for i := 1; i < ITER_N; i++ {
        out <- fmt.Sprintf("%d", i)
    }
    close(out)
}

func _goFuncN(in chan string, out chan string) {
    for j := range in {
        for i := 1; i < ITER_N; i++ {
            out <- fmt.Sprintf("%s,%d", j, i)
        }
    }
    close(out)
}

// ----------------

// create the pipeline
func IterDepth(d int) chan string {
    c1 := make(chan string)
    go _goFunc1(c1)

    var c2 chan string
    for ; d > 1; d-- {
        c2 = make(chan string)
        go _goFuncN(c1, c2)
        c1 = c2

    }
    return c1
}

You can test it with:

func main() {
    c := IterDepth(2)

    for i := range c {
        fmt.Println(i)
    }
}

I usually implement iterators using closures. Multiple dimensions don't make the problem much harder. Here's one example of how to do this:

package main

import "fmt"

func iter(min, max, depth int) func() ([]int, bool) {
    s := make([]int, depth)
    for i := range s { 
        s[i] = min 
    }   
    s[0] = min - 1 
    return func() ([]int, bool) {
        s[0]++
        for i := 0; i < depth-1; i++ {
            if s[i] >= max {
                s[i] = min 
                s[i+1]++
            }   
        }   
        if s[depth-1] >= max {
            return nil, false
        }   
        return s, true
    }   
}   

func main() {
    // Three dimensions, ranging between [1,4)
    i := iter(1, 4, 3)
    for s, ok := i(); ok; s, ok = i() {
        fmt.Println(s)
    }   

}

Try it out on the Playground.

It'd be a simple change for example to give arguments as a single int slice instead, so that you could have per-dimension limits, if such a thing were necessary.