考虑以下功能:
abstract class ObservableCollection<E> : CoroutineScope, MutableCollection<E> {...}
class ObservableList<E>(override val backingSource: MutableList<E> = mutableListOf()) : ObservableCollection<E>(), MutableList<E> by backingSource {...}
inline fun <reified T : Event<E>, E> ObservableCollection<E>.on(scope: CoroutineScope = this, noinline consumer: suspend (T) -> Unit): Job =
events.buffer(Channel.UNLIMITED)
.filterIsInstance<T>().onEach {
runCatching { consumer(it) }.onFailure { ObservableCollection.logger.catching(it) }
}.catch { ObservableCollection.logger.catching(it) }
.launchIn(scope)
首先,它是第一个通用的名称:
val list = ObservableList<Int>()
list.on<ElementAddEvent<Int>, Int> {
}
要使其更加惯用(以消除传递显式泛型的冗余),我们可以提供以下内容:
list.on { event: ElementAddEvent<Int> ->
}
但是还有一种方法可以删除<Int>
中的显式泛型{ event: ElementAddEvent<Int> ->
吗?由于它是隐式的,因为它来自调用了on
方法/函数的ObservableList类型。
Event<E>
基本上是诸如ElementRemoveEvent<E>
,ElementAddEvent<E>
,ElementReplaceEvent
等所有可能事件的接口。
interface Event<E> : CoroutineScope {
override val coroutineContext: CoroutineContext
get() = collection.coroutineContext
val collection: ObservableCollection<E>
}
class ElementAddEvent<E>(
val element: E,
override val collection: ObservableCollection<E>
) : Event<E>
class ElementReplaceEvent<E>(
val newElement: E,
val oldElement: E,
override val collection: ObservableCollection<E>
) : Event<E>
// And so-on...
基本上与这个问题无关,所以我没有提出。
一种方法可能是在每个事件中创建静态函数,例如:
class ElementAddEvent<E>(
val element: E,
override val collection: ObservableCollection<E>
) : Event<E> {
companion object {
fun <E> on(collection: ObservableCollection<E>, consumer: suspend (ElementAddEvent<E>) -> Unit) {
collection.on { event: ElementAddEvent<E> ->
consumer(event)
}
}
}
}
这将使它可以被调用为:
ElementAddEvent.on(list) {
}
但是我认为这会在源中产生过多的噪音 ,因此,我宁愿使用问题本身(指定类型)中发布的第二种方法在lambda中)。如果我错过了一个问题仍然存在,您可以让我知道!