我们有一个会被重复调用的lambda表达式:
1 2 3 4 5 6 7 8 9 10 11
| import kotlin.*
fun main() { val f: () -> Unit = { print("A") print("B") print("C") } f() f() }
|
我们给这个lambda加个参数:(String) -> Unit
,因为参数是个函数,为了能调用到函数,我们把它叫做emit
吧:
1 2 3 4 5 6 7 8 9 10 11
| import kotlin.*
fun main() { val f: ((String) -> Unit) -> Unit = { emit -> emit("A") emit("B") emit("C") } f { print(it) } f { print(it) } }
|
添加的参数看起来有点乱🤔,稍微修改一下,抽出来吧:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import kotlin.*
fun interface FlowCollector { fun emit(value: String) }
fun main() { val f: (FlowCollector) -> Unit = { it.emit("A") it.emit("B") it.emit("C") } f { print(it) } f { print(it) } }
|
好像能把it
的调用逻辑去掉,这样更简洁:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import kotlin.*
fun interface FlowCollector { fun emit(value: String) }
fun main() { val f: FlowCollector.() -> Unit = { emit("A") emit("B") emit("C") } f { print(it) } f { print(it) } }
|
调用lambda表达式不是很方便。如果把它抽成接口🤔
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import kotlin.*
fun interface FlowCollector { fun emit(value: String) }
interface Flow { fun collect(collector: FlowCollector) }
fun main() { val builder: FlowCollector.() -> Unit = { emit("A") emit("B") emit("C") } val flow: Flow = object : Flow { override fun collect(collector: FlowCollector) { collector.builder() } } flow.collect { print(it) } flow.collect { print(it) } }
|
抽成可以重复调用的构建器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import kotlin.*
fun interface FlowCollector { fun emit(value: String) }
interface Flow { fun collect(collector: FlowCollector) }
fun flow(builder: FlowCollector.() -> Unit) = object : Flow { override fun collect(collector: FlowCollector) { collector.builder() } }
fun main() { val f: Flow = flow { emit("A") emit("B") emit("C") } f.collect { print(it) } f.collect { print(it) } }
|
泛型化参数更通用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import kotlin.*
fun interface FlowCollector<T> { suspend fun emit(value: T) }
interface Flow<T> { suspend fun collect(collector: FlowCollector<T>) }
fun <T> flow(builder: suspend FlowCollector<T>.() -> Unit) = object : Flow<T> { override suspend fun collect(collector: FlowCollector<T>) { collector.builder() } }
suspend fun main() { val f: Flow<String> = flow { emit("A") emit("B") emit("C") } f.collect { print(it) } f.collect { print(it) } }
|
参考