Я изучаю параллелизм более подробно с Go.В книге, которую я читаю, приведен следующий пример, который в основном сжимает файлы из аргументов командной строки.
package main
import (
"compress/gzip"
"io"
"os"
)
func main() {
for _, file := range os.Args[1:] {
compress(file)
}
}
func compress(filename string) error {
in, err := os.Open(filename)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(filename + ".gz")
if err != nil {
return err
}
defer out.Close()
gzout := gzip.NewWriter(out)
_, err = io.Copy(gzout, in)
gzout.Close()
return err
}
Затем в книге объясняется, что если вы хотите обработать несколько сотен файлов, сохраните это такбудет определенно медленнее, чем если бы вы использовали goroutines, поэтому для их использования в функцию main()
вносится следующая модификация:
var wg sync.WaitGroup
var i int = -1
var file string
for i, file = range os.Args[1:] {
wg.Add(1)
go func(filename string) {
compress(filename)
wg.Done()
}(file)
}
wg.Wait()
fmt.Printf("Compressed %d files\n", i+1)
Затем следует отметить, что «обман» в отношениидля определения встроенной функции и ее параметра (имени файла) необходимо «потому что мы выполняем процедуры в цикле for».
Полагаю, я не понимаю, почему указанная выше встроенная функция необходима длязаставить это работать, разве нельзя использовать следующее, или я упускаю трюк?
for i, file = range os.Args[1:] {
wg.Add(1)
go compress(file)
wg.Done()
}
wg.Wait()
fmt.Printf("Compressed %d files\n", i+1)