Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗ktSpChSl 178 of 299 menu
◀ ▶

Выбор канала в Kotlin

Иногда нужно ждать данные сразу из нескольких очередей и реагировать на ту, где значение уже лежит. Конструкция select из kotlinx.coroutines.selects регистрирует ветки onReceive и выполняет одну из них, когда прием возможен без лишнего ожидания.

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

import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.runBlocking import kotlinx.coroutines.selects.onReceive import kotlinx.coroutines.selects.select fun main() { runBlocking { val hot = Channel<String>(1) val cold = Channel<String>(1) hot.send("H") cold.send("C") val picked = select { hot.onReceive { it } cold.onReceive { it } } println(picked) } }

В консоли окажется одна буква - "H" или "C". Функция select не читает оба канала сразу: срабатывает ровно одна ветка, остальные ждут следующего вызова.

Второй вызов select может забрать оставшееся значение из соседней очереди, если первая ветка уже опустошила свой канал:

import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.runBlocking import kotlinx.coroutines.selects.onReceive import kotlinx.coroutines.selects.select fun main() { runBlocking { val east = Channel<Int>(1) val west = Channel<Int>(1) east.send(10) west.send(20) val first = select { east.onReceive { it } west.onReceive { it } } val second = select { east.onReceive { it } west.onReceive { it } } println(first + second) } }

Сумма 30 показывает, что оба числа дошли до программы, хотя порядок веток в каждом select мог отличаться. Так объединяют несколько источников без жесткой привязки к одному каналу.

Два канала символов с буфером на один элемент содержат "p" и "q". Один select с двумя onReceive напечатайте выбранный символ.

Очереди строк "one" и "two" лежат в каналах с одним слотом. Два подряд select соберите обе строки в одну переменную через пробел и выведите ее.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить