Функция close

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

Синтаксис

goclose(ch)

Закрытие канала и чтение

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

gopackage main

import "fmt"

func main() {
  ch := make(chan int, 3)
  ch <- 1
  ch <- 2
  ch <- 3
  close(ch)

  for {
    val, ok := <-ch
    if !ok {
      break
    }
    fmt.Println(val)
  }
}

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

go1
2
3

При чтении из закрытого канала второе возвращаемое значение ok будет равно false, когда все значения из буфера уже прочитаны.

Использование range для чтения

Более удобный способ чтения из закрытого канала - использовать цикл range:

gopackage main

import "fmt"

func main() {
  ch := make(chan int, 2)
  ch <- 10
  ch <- 20
  close(ch)

  for val := range ch {
    fmt.Println(val)
  }
}

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

go10
20

Попытка отправки в закрытый канал

Попытка отправить данные в уже закрытый канал вызывает панику:

gopackage main

func main() {
  ch := make(chan int)
  close(ch)
  ch <- 42 // panic: send on closed channel
}

Закрытие nil канала

Попытка закрыть nil канал также вызывает панику:

gopackage main

func main() {
  var ch chan int
  close(ch) // panic: close of nil channel
}

Проверка закрытия канала

В горутинах часто используют конструкцию с проверкой второго возвращаемого значения:

gopackage main

import "fmt"

func main() {
  ch := make(chan string, 2)
  ch <- "a"
  ch <- "b"
  close(ch)

  for {
    val, ok := <-ch
    if !ok {
      fmt.Println("channel closed")
      break
    }
    fmt.Println("received:", val)
  }
}

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

goreceived: a
received: b
channel closed

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

  • функцию close-chan,
    которая описывает закрытие канала и его особенности
  • функцию chan,
    которая описывает создание каналов в Go
  • функцию send,
    которая описывает отправку данных в канал
  • функцию receive,
    которая описывает получение данных из канала