如何将 "join" sub 类 转换为超类型实例?
How to "join" sub classes into a super type instance?
如果我有一个接收 Callback
作为参数的函数,我如何使用 "collection" 或 "group" of sub-class/derived-class of Callback
这样,根据收到的参数,我可以 enable/disable 某些功能,如果收到 sub-class/derived-class "has" 或 "matches" 功能?
例如
import kotlin.random.Random
interface Callback
interface FruitsCallback : Callback {
fun onFruitsDeleted(ignored: Int)
}
interface VegetablesCallback : Callback {
fun onVegetablesDeleted(ignored: Int)
}
class FruitsStore : FruitsCallback {
override fun onFruitsDeleted(ignored: Int) {
throw NotImplementedError()
}
}
class VegetablesStore : VegetablesCallback {
override fun onVegetablesDeleted(ignored: Int) {
throw NotImplementedError()
}
}
fun delete(callback: Callback) {
if (callback is FruitsCallback) {
// Delete 5 fruits
callback.onFruitsDeleted(5)
}
if (callback is VegetablesCallback) {
// Delete 7 vegetables
callback.onVegetablesDeleted(7)
}
}
fun main() {
val fruitsStore = FruitsStore()
val vegetablesStore = VegetablesStore()
val callback: Callback = if (Random.nextBoolean()) {
fruitsStore + vegetablesStore
} else fruitsStore
delete(callback)
}
当我尝试执行 fruitsStore + vegetablesStore
时,错误出现在 main()
方法中。这显示类型不匹配问题。关于 kotlin 的 .plus()
.
可以做些什么
但是,在使用 coroutines
时,如何将以下类型添加在一起?
val exceptionHandler = CoroutineExceptionHandler { context, throwable -> println("$throwable") }
val coroutineContext = Dispatchers.Main + SupervisorJob() + exceptionHandler
我想知道 coroutineContext
如何能够接收一组这些类型的实例并将它们表示为一个。
我对科特林还很陌生。请解释:
- 为什么我做不到?
- 为什么协程可以做到?
- 这个叫什么?
- 如何在上面的示例中执行此操作?
协程 API 使用 operator overloading 让 +
运算符做一些它通常不能做的事情。如果您查看源代码,重载的加运算符的函数实例化了一个新的 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) }
}
}
}
}
如果Callback有第三种实现,上面的函数就会有七个分支。而且这里没有强制你如果添加额外的实现记得更新这个函数。
也就是说,您的 delete()
函数版本使用 is
是一种代码味道,未能利用多态性。在这种情况下,最好将 delete()
作为函数添加到 Callback
中,并且每个实现都可以自行定义其含义。
如果我有一个接收 Callback
作为参数的函数,我如何使用 "collection" 或 "group" of sub-class/derived-class of Callback
这样,根据收到的参数,我可以 enable/disable 某些功能,如果收到 sub-class/derived-class "has" 或 "matches" 功能?
例如
import kotlin.random.Random
interface Callback
interface FruitsCallback : Callback {
fun onFruitsDeleted(ignored: Int)
}
interface VegetablesCallback : Callback {
fun onVegetablesDeleted(ignored: Int)
}
class FruitsStore : FruitsCallback {
override fun onFruitsDeleted(ignored: Int) {
throw NotImplementedError()
}
}
class VegetablesStore : VegetablesCallback {
override fun onVegetablesDeleted(ignored: Int) {
throw NotImplementedError()
}
}
fun delete(callback: Callback) {
if (callback is FruitsCallback) {
// Delete 5 fruits
callback.onFruitsDeleted(5)
}
if (callback is VegetablesCallback) {
// Delete 7 vegetables
callback.onVegetablesDeleted(7)
}
}
fun main() {
val fruitsStore = FruitsStore()
val vegetablesStore = VegetablesStore()
val callback: Callback = if (Random.nextBoolean()) {
fruitsStore + vegetablesStore
} else fruitsStore
delete(callback)
}
当我尝试执行 fruitsStore + vegetablesStore
时,错误出现在 main()
方法中。这显示类型不匹配问题。关于 kotlin 的 .plus()
.
但是,在使用 coroutines
时,如何将以下类型添加在一起?
val exceptionHandler = CoroutineExceptionHandler { context, throwable -> println("$throwable") }
val coroutineContext = Dispatchers.Main + SupervisorJob() + exceptionHandler
我想知道 coroutineContext
如何能够接收一组这些类型的实例并将它们表示为一个。
我对科特林还很陌生。请解释:
- 为什么我做不到?
- 为什么协程可以做到?
- 这个叫什么?
- 如何在上面的示例中执行此操作?
协程 API 使用 operator overloading 让 +
运算符做一些它通常不能做的事情。如果您查看源代码,重载的加运算符的函数实例化了一个新的 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) }
}
}
}
}
如果Callback有第三种实现,上面的函数就会有七个分支。而且这里没有强制你如果添加额外的实现记得更新这个函数。
也就是说,您的 delete()
函数版本使用 is
是一种代码味道,未能利用多态性。在这种情况下,最好将 delete()
作为函数添加到 Callback
中,并且每个实现都可以自行定义其含义。