In Kotlin, Flow represents a cold stream concept. Similar to Stream in Java or Sequence in Kotlin, we can manipulate the data inside the flow (filter, transform, collect, etc). The Flow API, just like Stream and Sequence, offers two types of operations: intermediate and terminal. Intermediate operations again return a Flow instance, all other operations are considered terminal. As flows are naturally lazy, no operations will actually be started until a terminal operation is called.

This rule reports an issue when the result of an intermediate operation on Flow is left unused.

Noncompliant Code Example

suspend fun main() {
    val flow = flow {
        emit(1)
        emit(2)
        emit(3)
    }

    flow.take(2) // Noncompliant, the result of this operation is never used
}

Compliant Solution

suspend fun main() {
    val flow = flow {
        emit(1)
        emit(2)
        emit(3)
    }

    flow.take(2).collect { println(it) } // Compliant, collect is a terminal operation
}

See