У меня есть фрагмент кода ниже
package main
import (
"fmt"
"net/http"
"time"
)
func checkLink(url string, ch chan string) {
_, err := http.Get(url)
if err != nil {
fmt.Println(url, "Did not respond")
ch <- "Did not respond I think"
return
}
fmt.Println(url, "responded normally!")
ch <- url
}
func main() {
urls := []string{
"https://google.com",
"https://amazon.com",
"https://facebook.com",
"https://golang.org",
"https://stackoverflow.com",
}
c := make(chan string)
for _, url := range urls {
go checkLink(url, c)
}
for url := range c {
go func() {
time.Sleep(5 * time.Second)
checkLink(url, c)
}()
}
}
и это выход
https://golang.org responded normally!
https://stackoverflow.com responded normally!
https://google.com responded normally!
https://facebook.com responded normally!
https://amazon.com responded normally!
https://amazon.com responded normally!
https://amazon.com responded normally!
https://amazon.com responded normally!
https://amazon.com responded normally!
https://amazon.com responded normally!
https://amazon.com responded normally!
https://amazon.com responded normally!
https://amazon.com responded normally!
https://amazon.com responded normally!
https://amazon.com responded normally!
и после поиска я обнаружил, что мне нужно передать переменную url
в литеральную функцию и заставить ее принимать строковую переменную, как показано ниже.
for url := range c {
go func(url string) {
time.Sleep(5 * time.Second)
checkLink(url, c)
}(url)
}
но я не понял почему. и почему URL-адрес amazon.com
продолжал печатать так, а переменная URL не обновлялась?
url
— это переменная цикла, которая повторно используется в каждой итерации, и если ваша анонимная функция (запущенная как горутина) ссылается на нее, то ее значение не останется тем, которое было присвоено ей при запуске горутины. Это также гонка данных и, как таковое, неопределенное поведение. - person icza   schedule 08.07.2021url
. Когда вы не передаетеurl
в функцию, вы продолжаете ссылаться на исходную переменную, а не на исходное значение. Передаваяurl
в качестве параметра, параметр сохраняет значение в течение 5-секундного ожидания даже при изменении переменной цикла. Это становится намного более очевидным, когда параметр внутренней функции не затеняет переменную цикла. - person Corey Ogburn   schedule 08.07.2021