본문 바로가기

개발/코틀린

Flow 동작 이해

 

// code 1 
interface Flow<out T> {
	suspend fun collect(collecotr: FlowCollector<T>)
}

interface FlowCollector<in T> {
	suspend fun emit(value: T)
}
// code 3
flow {
    emit(1)      
    emit(2)
} 
// 1
.collect {
    println(it)  
} 
// 2

// code 4
public fun <T> flow(@BuilderInference block: suspend FlowCollector<T>.() -> Unit): Flow<T> = SafeFlow(block)

// Named anonymous object
private class SafeFlow<T>(private val block: suspend FlowCollector<T>.() -> Unit) : AbstractFlow<T>() {
    override suspend fun collectSafely(collector: FlowCollector<T>) {
        collector.block()
    }
}
  • flow를 이해하기 어려운 이유는 람다와 sam 구조로 인한 생략 때문(내 개인적 느낌)
  • code 3과 code 4를 보면 주석1까지는 SafeFlow클래스를 생성한것임
    • SafeFlow는 Flow의 구현체임
    • flow의 액션람다는 FlowCollector리시버
  • 주석2에서 SafeFlow의 collect함수를 호출함
    • 그러면, collectSafely 함수가 호출됨
    • collectSafely 내부에서는 collector.block이 호출되고 있으니까 1번의 flow의 액션 람다가 호출되는 것임
    • 액션람다에서는 (눈을 크게뜨면) FlowCollector.emit을 호출하고있는 것임
    • FlowCollector.emit함수의 실제 본문은 2번 액션람다임
    • 즉 println이 호출 됨
    • 그래서 println 1, println 2가 차례로 호출됨

 

'개발 > 코틀린' 카테고리의 다른 글

코틀린 코루틴 내부 동작 이해하기  (0) 2023.12.28
변성 - 공변, 무공변, 반공변  (0) 2020.11.22