我正在尝试构建一个可以向其注册外部模块的Synchronization类,但是我无法使泛型部分起作用。
外部模块将在SynchronizationBundle<SynchronizableType>
上注册Synchronizator
,然后应处理同步。
interface Synchronizable<T : Synchronizable<T>>
object SynchronizationBundles {
val bundles: MutableMap<KClass<*>, SynchronizableBundle<*>> = mutableMapOf()
fun <T : Synchronizable<T>> register(kClass: KClass<T>, bundle: SynchronizableBundle<T>) {
bundles[kClass] = bundle
}
@Suppress("UNCHECKED_CAST")
operator fun <T: Synchronizable<T>> get(kClass: KClass<T>) : SynchronizableBundle<T> {
return bundles[kClass] as? SynchronizableBundle<T> ?: throw IllegalArgumentException("No bundle for ${kClass.simpleName}")
}
}
例如,在同步操作上,它应该遍历已注册的包,并能够使用
Synchronizable<T>
的特定实现。伪代码前面fun synchronize() {
bundles.forEach { bundleEntry ->
val bundle = bundles[bundleEntry.key]
val synchronizables = bundle.api.get()
remoteSynchronizables.forEach { remoteSynchronizable ->
val localSynchronizable = bundle.datastore.getByPlatformId(remoteSynchronizable.platformId)
val synchronizableToInsert = bundle.conflictStrategy.resolve(localSynchronizable, remoteSynchronizable)
synchronizableToInsert?.let {
bundle.datastore.insert(it.withUploadStatus(UploadStatus.COMPLETED))
}
}
}
}
问题是
val bundle = bundles[bundleEntry.key]
返回了SynchronizableBundle<*>
,因此我无法调用.conflictStrategy.resolve
,因为它需要Synchronizable<T>
例如,这是
ConflictStrategy
定义。 api和数据存储遵循相同的模式interface ConflictStrategy<T : Synchronizable<T>>
这有可能吗?我确定我不是第一个尝试这种方法的人。
如果我能以某种方式调用
val bundle = bundles[MySynchronizable::class]
,我会得到一个SynchronizableBundle<MySynchronizable>
,但我没有成功做到这一点。另外,类型Synchronizator
将使用的类型将在外部模块中,所以我什至不知道构建特定的KClass
是否可行。使用高阶函数可能会使我的生活更轻松,并且此Synchronizator可能与类型无关,但我没有尝试过。
谢谢!
最佳答案
在下文中,我对代码进行了一些简化,以演示如何从外部使用此包管理器:
object Bundles{
private val bundles: MutableMap<KClass<*>, Bundle<*>> = mutableMapOf()
fun <T> register(c: KClass<T>, b: Bundle<T>){
bundles[c]= b
}
operator fun <T> get(kClass: KClass<T>) : Bundle<T> {
return bundles[kClass] as? Bundle<T> ?: throw IllegalArgumentException("No bundle for ${kClass.simpleName}")
}
}
fun main(args: Array<String>) {
Bundles.register(String::class, Bundle())
Bundles.register(Int::class, Bundle())
Bundles.register(Number::class, Bundle())
val stringBundle = Bundles[String::class]
val intBundle = Bundles[Int::class]
val numBundle = Bundles[Number::class]
}
您已经注意到这可行。现在,您尝试将
bundles
循环到SynchronizationBundles
中。在这一点上,您不知道已添加到bundles
中的内容,因此无法从中获取具体实例。恐怕您必须研究其他方法。