Что означает потребление Котлинского канала? - PullRequest
0 голосов
/ 19 ноября 2018

Документы Kotlin используют термин consume как для описания поведения таких методов, как Channel#first(), так и в именах таких методов, как Channel#consumeEach().

Мне трудно понять, что означает использование канала по сравнению с неиспользованным.

Как вообще выглядит непотребление?

Разрешает ли API канала доступ к элементам в канале без потребления?

Кроме consumeEach(), всегда ли потребление означает полное опустошение канала?

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Вывод следующего кода иллюстрирует значение «потребления» и эффект consumeEach.

fun f1() = runBlocking {
    val numbers = produce {
        repeat(5) {
            send(it)
            delay(100)
        }
    }
    run {
        for (i in numbers) {
            trace(i)
            if (i == 2) return@run
        }
    }
    trace("after run")
    for (i in numbers) {
        trace(i)
    }
    trace("exiting f1")
}
f1()

println()

fun f2() = runBlocking {
    val numbers = produce {
        repeat(5) {
            send(it)
            delay(100)
        }
    }
    run {
        numbers.consumeEach {
            trace(it)
            if (it == 2) return@run
        }
    }
    trace("after run")
    for (i in numbers) {
        trace(i)
    }
    trace("exiting f2")
}
f2()

Вывод:

[main @coroutine#1]: 0
[main @coroutine#1]: 1
[main @coroutine#1]: 2
[main @coroutine#1]: after run
[main @coroutine#1]: 3
[main @coroutine#1]: 4
[main @coroutine#1]: exiting f1

[main @coroutine#3]: 0
[main @coroutine#3]: 1
[main @coroutine#3]: 2
[main @coroutine#3]: after run
[main @coroutine#3]: exiting f2

Мы видим, что (в f1) мы можем прекратить итерации по каналу, а затем продолжить, где мы остановились.Однако при использовании consumeEach (в f2) мы не можем остановиться и продолжить, даже если канал изначально был способен генерировать числа, превышающие 2.

0 голосов
/ 19 ноября 2018

Использование «потреблять» означает, что это действие терминала, что ничто за пределами этой команды не может считывать данные из канала.Это яснее можно увидеть в документации API для first и consumeEach:

Операция является терминальной.Эта функция использует все элементы исходного ReceiveChannel.

Обратите внимание, что в документах также содержатся предупреждения о том, что этот API изменится в будущем.

Read KT-167 для полезных комментариев по этой теме.

...