Привет всем! Есть тут те кто могёт в Go? Есть такая задачка: Измените программу так, чтобы цифры от 1 до 9 печатались в консоль по порядку (Golang). Разрешено внести изменения в участки кода, помеченные комментарием «// redact». Code: package main import "time" func main() { // redact go func() { for _, value := range []int{1, 4, 7} { // redact println(value) // redact } }() go func() { for _, value := range []int{2, 5, 8} { // redact println(value) // redact } }() go func() { for _, value := range []int{3, 6, 9} { // redact println(value) // redact } }() time.Sleep(time.Second) } Я решил эту задачу так: Code: package main import "time" func main() { preOutValue := make(chan int, 1) // Создаем канал defer close(preOutValue) // Не закрывать канал до завершения main() preOutValue <- 1 // Закидываем в канал значание 1 типа int go func() { for _, value := range []int{1, 4, 7} { for { tmpval1 := <-preOutValue // Достаем значение из канала в переменную tmpval1 if tmpval1 == value { // если полученное значение соответствует value println(value) // Выводим value preOutValue <- value + 1 // Отправляем в канал значение на 1 больше break } else { preOutValue <- tmpval1 // Если сообщение из канала не совпало с нашим, закинем его обратно } } } }() go func() { for _, value := range []int{2, 5, 8} { for { tmpval2 := <-preOutValue if tmpval2 == value { println(value) preOutValue <- value + 1 break } else { preOutValue <- tmpval2 } } } }() go func() { for _, value := range []int{3, 6, 9} { for { tmpval3 := <-preOutValue if tmpval3 == value { println(value) preOutValue <- value + 1 break } else { preOutValue <- tmpval3 } } } }() time.Sleep(time.Second) } Но мне говорят что это неправильно, а как правильно не сказали. Кто знает как правильно? P.S. Базово изучил язык за 1-ну ночь, так что PLZ сильно не пинать.
Не знаком с go, но по логике просится sleep. Тормозя итерацию в каждом блоке (time.Sleep(time.Millisecond * X)), можно добиться последовательной выдачи результатов.
Да нет, вопрос в том что мой код(моё решение) выдает правильный результат, мне просто сказали что сам код написан неправильно(типа быдлокод), а почему не сказали
Привет, Сначала по твоему решению: Code: defer close(preOutValue) // Не закрывать канал до завершения main() В комментарии ты неправильно описываешь логику работы defer: https://golang.org/doc/effective_go.html#defer Далее тут: Code: for { tmpval1 := <-preOutValue // Достаем значение из канала в переменную tmpval1 if tmpval1 == value { // если полученное значение соответствует value println(value) // Выводим value preOutValue <- value + 1 // Отправляем в канал значение на 1 больше break } else { preOutValue <- tmpval1 // Если сообщение из канала не совпало с нашим, закинем его обратно } } Теоретически может возникнуть ситуация, когда две из трёх горутин повиснут на этом канале и третяя никогда не сработает. Такая, пусть и маловероятная, ситуация делает твой код некорректным. Ещё этот for-цикл не выглядит очень изящным в то время как язык предоставляет тебе уйму средств для асинхронного программирования и синхронизации. Далее пара изменённых версий этого же задания: Code: package main import "time" func main() { c1, c2, c3 := make(chan bool, 1), make(chan bool, 1), make(chan bool, 1) defer close(c1) defer close(c2) defer close(c3) c1 <- true go func() { for _, value := range []int{1, 4, 7} { <-c1 println(value) c2 <- true } }() go func() { for _, value := range []int{2, 5, 8} { <-c2 println(value) c3 <- true } }() go func() { for _, value := range []int{3, 6, 9} { <-c3 println(value) c1 <- true } }() time.Sleep(time.Second) } Code: package main import "time" func main() { go func() { for _, value := range []int{1, 4, 7} { for i := 1; i < 10; i++ { println(i) } break println(value) } }() go func() { for _, value := range []int{2, 5, 8} { break println(value) } }() go func() { for _, value := range []int{3, 6, 9} { break println(value) } }() time.Sleep(time.Second) }
Т.е. тут, фактически, когда дело доходит до "<-c1" , поток залипает в ожидании числа из канала? Т.е. это, как бы, работа по событию? И когда потоки запустились, они фактически стоят и ждут пока что-то не прилетит из канала? Я правильно понял?