首页 新闻 会员 周边 捐助

Golang,为何for-loop的条件判断与for控制块里做if判断存在区别

0
悬赏园豆:30 [已解决问题] 解决于 2022-07-25 19:07

如下是我的测试代码(一个素数筛),注释掉的方式会跑超时。

// go test -timeout 30s -run ^TestChannelPrime$ package-path -v
func TestChannelPrime(t *testing.T) {
    for i := range primeGenerator() {
        if i > 13 {
            break
        }
        t.Log(i)
    }
}

func primeGenerator() <-chan int {
    res := make(chan int)
    // 2 ->
    // 3    3 ->
    // 4
    // 5    5    5 ->
    // 6
    // 7    7    7
    // 9    9
    go func() {
        for curChannel := func() <-chan int {
            naturalNumber := make(chan int)
            go func() {
                for i := 2; ; i++ {
                    naturalNumber <- i
                }
            }()
            return naturalNumber
        }(); ; {
            curPrimeNumber := <-curChannel
            res <- curPrimeNumber
            curChannel = func(curChan <-chan int, curPrime int) <-chan int {
                nextChan := make(chan int)
                go func() {
                    for {
                        if i := <-curChan; i%curPrime != 0 {
                            nextChan <- i
                        }
                    }
                    // for i := <-curChan; i%curPrime != 0; {
                    //     nextChan <- i
                    // }
                }()
                return nextChan
            }(curChannel, curPrimeNumber)
        }
    }()
    return res
}
问题补充:

顺便,想问一下,闭包和传参存在差异(测试代码中curChancurPrime的位置),谁能阐释一下

joel-q的主页 joel-q | 初学一级 | 园豆:177
提问于:2022-07-23 23:44
< >
分享
最佳答案
0

问题:Golang,为何for-loop的条件判断与for控制块里做if判断存在区别
答:其实跟golang没关系,这两个for代码块的区别是,注释掉的代码中的条件判断为否就跳出循环了,而预期是死循环,只是是否取值是根据条件判断的。

补充问题:闭包和传参存在差异(测试代码中curChan和curPrime的位置)
答:golang的匿名函数,即函数字面量就是闭包,不同于Java,golang中被闭包的对象是共享的,也是可修改的(见问题评论)。这里的代码,curChan必须从curChannel拷贝值已形成自己的输出通道,否则,如果只用闭包的curChannel,那么,所有函数字面量协程的输出通道都将指向(其实是值赋值、完全被新值覆盖)同一个新的curChannel。而这里的curPrimeNumber其实是可以用闭包的,因为在外层循环的每一次,curPrimeNumber都是一个全新赋值的局部对象,这也许就是用:=将初始化凸显出来的缘由。更新后的代码见:https://www.cnblogs.com/qqiwei/p/16513559.html

joel-q | 初学一级 |园豆:177 | 2022-07-25 18:46
其他回答(1)
1

函数单独定义出来,代码能清晰很多。
闭包如果引用了外部的变量,那么外部变量变了,闭包中引用的变量也会变。
而传参的话,外部变量传入函数之后,外部变量变了,函数内的变量不会变。

收获园豆:30
wang_yb | 园豆:4891 (老鸟四级) | 2022-07-24 10:59
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册