Канал chan

Канал chan представляет собой типизированный конвейер, через который горутины могут отправлять и получать данные для синхронизации и обмена информацией. При объявлении канала указывается тип передаваемых значений.

Каналы бывают небуферизированными и буферизированными. Небуферизированный канал блокирует отправку до тех пор, пока другая горутина не выполнит операцию приема. Буферизированный канал позволяет отправлять данные до тех пор, пока буфер не заполнится.

Синтаксис

goch := make(chan int)      // небуферизированный канал для int
ch := make(chan string, 5)  // буферизированный канал для string

Для создания канала используется встроенная функция make, которой передается тип канала с указанием типа данных и опционально - вместимость буфера.

Пример

Давайте создадим небуферизированный канал для передачи строк между горутинами:

gopackage main

import "fmt"

func main() {
  ch := make(chan string)

  go func() {
    ch <- "Hello from goroutine"
  }()

  msg := <-ch
  fmt.Println(msg)
}

Результат выполнения кода:

go"Hello from goroutine"

В этом примере мы создали канал ch для строк, запустили горутину, которая отправляет в него сообщение, и в основной горутине получили это сообщение.

Пример

Давайте создадим буферизированный канал на 2 элемента и отправим в него несколько значений без блокировки:

gopackage main

import "fmt"

func main() {
  ch := make(chan int, 2)

  ch <- 1
  ch <- 2

  fmt.Println(<-ch)
  fmt.Println(<-ch)
}

Результат выполнения кода:

go1
2

Буферизированный канал позволяет отправлять значения без ожидания получателя, пока буфер не заполнится.

Пример

Давайте используем канал для передачи результата длительной операции из горутины:

gopackage main

import "fmt"

func main() {
  ch := make(chan int)

  go func() {
    result := 0
    for i := 1; i <= 5; i++ {
      result += i
    }
    ch <- result
  }()

  res := <-ch
  fmt.Println(res)
}

Результат выполнения кода:

go15

Каналы обеспечивают безопасную передачу данных между горутинами без использования явных блокировок.

Смотрите также

  • оператор send,
    который используется для отправки данных в канал
  • оператор receive,
    который используется для получения данных из канала
  • конструкцию select,
    которая позволяет ожидать несколько операций с каналами
  • функцию close-chan,
    которая закрывает канал для дальнейшей отправки данных