星空投影系列中的特定KClass

时间:2018-12-06 07:44:49

标签: generics kotlin

我正在尝试构建一个可以注册外部模块的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>

例如,在 synchronize 操作上,它应遍历已注册的包,并能够使用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

例如,这是interface ConflictStrategy<T : Synchronizable<T>> 的定义。 Api和数据存储区遵循相同的模式

val bundle = bundles[MySynchronizable::class]

这甚至可能吗?我确定我不是第一个尝试这种方法的人。

如果我能以某种方式调用SynchronizableBundle<MySynchronizable>,我会得到一个Synchronizator,但我没有成功做到这一点。另外,类型KClass将使用的类型将在外部模块中,所以我什至不知道构建特定的foreach($data as $key=>$val) { if($val->username == $username && $val->password == md5($password) ) { $flag=true; $newdata =array('name'=>$val->name,'username'=>$username); $this->session->set_userdata($newdata); break; } 是否可行。

使用高阶函数可能会使我的生活更轻松,并且此Synchronizator可能与类型无关,但我没有尝试过。

谢谢!

1 个答案:

答案 0 :(得分:1)

下面,我对代码进行了一些简化,以演示如何从外部使用此包管理器:

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中的内容,因此无法从中获取具体实例。恐怕您必须研究其他方法。