1. 贴代码的时候注意格式。你贴成这样鬼知道代码长啥样
2. 贴代码的时候把无关代码注释掉。比如 thumbnail.ImageFile(file)
3. 你上面贴的那一段代码格式化好以后大概长这样
===========================================
package main
import (
"fmt"
)
func makethumbnail2(filename []string) {
ch := make(chan struct{})
for _, file := range filename {
file = file
go func() {
fmt.Println(file)
//thumbnail.ImageFile(file)
ch <- struct{}{}
}()
}
for range filename {
<-ch
}
}
func main() {
var files []string
for i := 0; i < 100; i++ {
files = append(files, fmt.Sprintf("file%d", i))
}
makethumbnail2(files)
}
====================================
4. 下面来解答你的问题
1.1 你在 func() 里面 捕获了 file 变量。而 go 的捕获机制是按照引用捕获。 也就是说,如果我们在 func()外部改变 file 的值, func()内部的 file 也会受到影响
1.2 你的 func()是在另一个 goroutine 里面执行的。也就是说,一方面有 N 多个 func()在不同的 goroutine 里面执行。一方面第一个 for range 循环又在改变 file 的值。在第一个 for range 完成之前,你看到的输出应该是随缘产生的。而 for range 完成之后,则会输出最后一个文件名。
1.3 至于楼主的四个随机文件,那单纯是因为输出了 4 个文件以后,第一个 for range 完成了。
1.4 上面那段测试代码在我的环境下运行只输出了 10 个 file99
1.5 参考资料
https://www.goinggo.net/2014/06/pitfalls-with-closures-in-go.html