Как в Go узнать ёмкость (capacity) и текущую длину (length) канала?

Ответ

В Go для работы с размерами канала используются две встроенные функции: cap() для ёмкости и len() для текущего количества элементов.

1. Ёмкость канала — cap()

Функция cap() возвращает ёмкость (capacity) канала, то есть размер его буфера. Это максимальное количество элементов, которое можно отправить в канал без блокировки.

  • Для буферизированных каналов cap() вернет размер буфера, указанный при создании.
  • Для небуферизированных каналов cap() всегда возвращает 0.
// Буферизированный канал
bufChan := make(chan int, 5)
fmt.Println(cap(bufChan)) // Вывод: 5

// Небуферизированный канал
unbufChan := make(chan int)
fmt.Println(cap(unbufChan)) // Вывод: 0

2. Текущее количество элементов — len()

Функция len() возвращает текущее количество элементов, находящихся в буфере канала.

ch := make(chan int, 3)
fmt.Printf("Ёмкость: %d, Длина: %dn", cap(ch), len(ch))

ch <- 1
ch <- 2
fmt.Printf("Ёмкость: %d, Длина: %dn", cap(ch), len(ch))

<-ch
fmt.Printf("Ёмкость: %d, Длина: %dn", cap(ch), len(ch))

// Вывод:
// Ёмкость: 3, Длина: 0
// Ёмкость: 3, Длина: 2
// Ёмкость: 3, Длина: 1

⚠️ Важное замечание: В реальном коде редко полагаются на len() для управления потоком данных в конкурентных программах. Состояние канала может измениться между вызовом len() и следующей операцией. Вместо этого используются блокирующие операции чтения/записи, select или закрытие канала для синхронизации горутин.