πŸ’¬ Π§Ρ‚ΠΎ происходит с замыканиями, выполняСмыми ΠΊΠ°ΠΊ Π³ΠΎΡ€ΡƒΡ‚ΠΈΠ½Ρ‹?



ΠŸΡ€ΠΈ использовании Π·Π°ΠΌΡ‹ΠΊΠ°Π½ΠΈΠΉ с ΠΊΠΎΠ½ΠΊΡƒΡ€Π΅Π½Ρ‚Π½ΠΎΡΡ‚ΡŒΡŽ ΠΌΠΎΠΆΠ΅Ρ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ ΠΏΡƒΡ‚Π°Π½ΠΈΡ†Π°. Рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€:



func main() {

done := make(chan bool)



values := []string{"a", "b", "c"}

for _, v := range values {

go func() {

fmt.Println(v)

done <- true

}()

}



// ΠΆΠ΄Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ всСх Π³ΠΎΡ€ΡƒΡ‚ΠΈΠ½ ΠΏΠ΅Ρ€Π΅Π΄ Π²Ρ‹Ρ…ΠΎΠ΄ΠΎΠΌ

for _ = range values {

<-done

}

}





МоТно ΠΎΡˆΠΈΠ±ΠΎΡ‡Π½ΠΎ ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π²Ρ‹Π²ΠΎΠ΄: a, b, c. ВмСсто этого ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ c, c, c. Π­Ρ‚ΠΎ происходит ΠΏΠΎΡ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ каТдая итСрация Ρ†ΠΈΠΊΠ»Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ экзСмпляр ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ v, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ Π·Π°ΠΌΡ‹ΠΊΠ°Π½ΠΈΠ΅ дСлится этой СдинствСнной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ.



Когда Π·Π°ΠΌΡ‹ΠΊΠ°Π½ΠΈΠ΅ выполняСтся, ΠΎΠ½ΠΎ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ v Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ выполнСния fmt.Println, Π½ΠΎ v ΠΌΠΎΠ³Π»Π° ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒΡΡ с ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° запуска Π³ΠΎΡ€ΡƒΡ‚ΠΈΠ½Ρ‹. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠΌΠΎΡ‡ΡŒ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚ΡŒ эту ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π΄ΠΎ ΠΈΡ… возникновСния, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ go vet.



Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈΠ²ΡΠ·Π°Ρ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ v ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ Π·Π°ΠΌΡ‹ΠΊΠ°Π½ΠΈΡŽ ΠΏΡ€ΠΈ Π΅Π³ΠΎ запускС, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ Ρ†ΠΈΠΊΠ» Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΈ создавалась новая пСрСмСнная. Один ΠΈΠ· способов β€” ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Π² качСствС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° Π·Π°ΠΌΡ‹ΠΊΠ°Π½ΠΈΡŽ:



for _, v := range values {

go func(u string) {

fmt.Println(u)

done <- true

}(v)

}





Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ v пСрСдаСтся Π² качСствС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° Π°Π½ΠΎΠ½ΠΈΠΌΠ½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Π­Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π·Π°Ρ‚Π΅ΠΌ доступно Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΊΠ°ΠΊ пСрСмСнная u.



Π•Ρ‰Π΅ ΠΏΡ€ΠΎΡ‰Π΅ β€” ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½ΠΎΠ²ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΡΡ‚ΠΈΠ»ΡŒ объявлСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ странным, Π½ΠΎ Π² Go Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ…ΠΎΡ€ΠΎΡˆΠΎ:



for _, v := range values {

v := v // создаСм Π½ΠΎΠ²ΡƒΡŽ 'v'.

go func() {

fmt.Println(v)

done <- true

}()

}