В зависимости от , когда выполняется обратный вызов, может потребоваться создать копию переменной итерации внутри блока и использовать ее в замыкании.
for _, selector := range listSelector {
sel := selector // create a copy
c.OnHTML(sel, func(e *colly.HTMLElement) {
fmt.Println(sel) // Similar outputs
})
}
Если обратный вызоввыполняется, и он выходит перед следующей итерацией в цикле, вам не нужно этого делать, однако, если обратный вызов выполняется некоторое время спустя, вам необходимо передать копию переменной итерации в замыкание. Это связано с тем, что переменная итерации повторно используется для хранения значений повторения, что означает, что значение переменной из текущей итерации будет перезаписано значением из следующей итерации.
From spec :
Переменные итерации могут быть объявлены предложением «range» с использованием формы краткого объявления переменных (: =). В этом случае их типам присваиваются типы соответствующих значений итерации, а их область действия является блоком оператора for; они повторно используются в каждой итерации . Если переменные итерации объявлены вне оператора for, после выполнения их значения будут такими же, как в последней итерации.
Если вам интересно, это лучше объяснить в *Документация по каналам 1021 * Effective Go .