API сопрограммы использует перегрузку оператора , чтобы заставить оператор +
делать то, что он обычно не может. Если вы посмотрите на исходный код, функция оператора перегруженного плюса создает новый CoroutineContext, который скопировал значения свойств обоих операндов.
В вашем случае, чтобы это работало, вам придется написать свою собственную операторскую функцию. Но попытка реализовать несколько интерфейсов условно становится очень сложной очень быстро. В вашем примере есть только два возможных типа обратного вызова, и это уже делает длинную функцию с тремя ветвями:
operator fun Callback.plus(other: Callback): Callback {
val callbacks = listOf(this, other)
return when {
callbacks.all { it is FruitsCallback } -> object: FruitsCallback {
override fun onFruitsDeleted(ignored: Int) {
callbacks.forEach { (it as FruitsCallback).onFruitsDeleted(ignored) }
}
}
callbacks.all { it is VegetablesCallback } -> object : VegetablesCallback {
override fun onVegetablesDeleted(ignored: Int) {
callbacks.forEach { (it as VegetablesCallback).onVegetablesDeleted(ignored) }
}
}
else -> object: FruitsCallback, VegetablesCallback {
override fun onFruitsDeleted(ignored: Int) {
callbacks.forEach { (it as? FruitsCallback)?.onFruitsDeleted(ignored) }
}
override fun onVegetablesDeleted(ignored: Int) {
callbacks.forEach { (it as? VegetablesCallback)?.onVegetablesDeleted(ignored) }
}
}
}
}
Если бы существовала третья реализация обратного вызова, вышеуказанная функция имела бы семь ветвей , И здесь нет никакого принуждения, что вы не забудете обновить эту функцию, если добавите дополнительные реализации.
Тем не менее, ваша версия использования delete()
функции *1013* - это запах кода, отказ от использования полиморфизма , В этом случае было бы лучше добавить delete()
как функцию в Callback
, и каждая реализация может определить для себя, что это должно означать.