Как я упоминал в своем первом посте, я немного изучаю Go. Сегодня я столкнулся с горутинами, которые, по сути, представляют собой функции или методы, которые выполняются одновременно, в виде «потоков».

Итак, если у нас есть (очень простой) код:

func main() {
   go makeSureBothStatementsGetInThere()
   fmt.Println("We are executed concurrently.")
}

func makeSureBothStatementsGetInThere() {
   fmt.Println("We are executed concurrently.")
}

что произойдет, так это то, что go вызовет makeSureBothStatementsGetInThere() одновременно с оператором fmt.Println под ним. Таким образом, можно напечатать одновыражение на экране, или обавывода на экране. Мы не узнаем заранее.

Вот где вступают каналы:

func main() {
   quitSignal := make(chan bool)

   go makeSureBothStatementsGetInThere(quitSignal)
   fmt.Println("We are executed concurrently.")
   <-quitSignal
}

func makeSureBothStatementsGetInThere(channel chan bool) {
   fmt.Println("We are executed concurrently.")
   channel <- true
}

Теперь программа будет ожидать quitSignal перед выходом, обеспечивая вывод обоих операторов на экран.

Я думаю, что это довольно простой способ выполнить очень сложную задачу (т. е., по сути, многопоточность). Go выглядит довольно аккуратно.

[ОБНОВЛЕНИЕ] Я немного углубился в горутины и изучил шаблон проектирования, который кажется невероятно полезным при разработке приложений Go. Предположим, у вас есть много кода в приложении, которое вы хотите запускать одновременно с остальной частью вашего приложения. Один из способов сделать это — использовать «генератор горутин».

Мы определяем функцию waitThenSend():

func waitThenSend(i, value int) chan int {
   channel := make(chan int)

   go func() {
      time.Sleep(time.Duration(i) * time.Second)
      channel <- value
   }()

   return channel
}

Это можно вызвать в нашей функции main(), например:

func main() {
   fmt.Println(<-waitThenSend(3, 42))
}

Что случится? Программа подождет три секунды, а затем выведет целое число 42. Используя этот шаблон, мы можем поместить любой код, который хотим выполнять одновременно, в горутину функции генератора, а затем просто вызвать функцию генератора, когда это необходимо.

Очень интересно и, уверен, невероятно полезно.