Как мне бросить универсальный тип для указанного c типа, так что он может быть запущен в универсальной функции? - PullRequest
0 голосов
/ 13 февраля 2020

У меня есть функция replaceCollection, для замены которой требуется два MongoCollection<T>.

Объявление функции выглядит следующим образом.

private suspend fun <T> replaceCol(old: MongoCollection<T>, new: MongoCollection<T>, session: ClientSession)

Работает нормально, когда я добавляю два MongoCollection<SameClass> в функцию. Тем не менее, у меня есть список коллекций, которые я хотел бы заменить, но я не могу найти способ приведения <out Any>, чтобы гарантировать компилятору, что они имеют одинаковый тип, так что его можно запустить в функции generi c replaceCol

//oldCols[i] and newCols[i] always have the same generic type 
val oldCols: Array<MongoCollection<out Any>> = ...
val newCols: Array<MongoCollection<out Any>> = ...

for(i in prodCols.indices) {
    replaceCol(preProdCols[i], prodCols[i], session)
}   

/* error on the line of replaceCol
Type inference failed: Cannot infer type parameter T in //...
None of the following substitutions
(
MongoCollection<CapturedTypeConstructor(out Any)>,
MongoCollection<CapturedTypeConstructor(out Any)>,
ClientSession
)
(
MongoCollection<CapturedTypeConstructor(out Any)>,
MongoCollection<CapturedTypeConstructor(out Any)>,
ClientSession
)
can be applied to
(
MongoCollection<out Any>,
MongoCollection<out Any>,
ClientSession!
)
*/

1 Ответ

0 голосов
/ 13 февраля 2020

Если вы на 100% уверены , что коллекции с одинаковыми индексами имеют одинаковые типы c, вы можете использовать непроверенное приведение:

fun <T> replaceArray(old: Array<T>, new: Array<T>) {
    old[0] = new[0]
}

fun <T> forceReplace(old: Array<T>, new: Array<*>) {
    @Suppress("UNCHECKED_CAST")
    replaceArray(old, new as Array<T>)
}

fun main() {
    val old = arrayOf<Array<out Any>>(
        arrayOf(0),
        arrayOf("!")
    )
    val new = arrayOf<Array<out Any>>(
        arrayOf(1),
        arrayOf("?")
    )
    for (i in old.indices) {
        forceReplace(old[i], new[i])
    }
}

Но все же лучше способ решить вашу проблему - изменить дизайн вашей логики c, поэтому вам не нужны такие обходные пути.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...