Непроверенный актерский состав на родовом заводе Котлин - PullRequest
1 голос
/ 08 марта 2019

Я пытаюсь создать универсальную фабрику в kotlin для разбора некоторой строки на классы Model:

internal interface Model

data class UserId(val id: String, val name: String, val link: String): Model
data class Shelf(val id: String, val name: String, val bookCount: Int): Model

internal inline fun <reified T: Model> getParser(): Parser<T> {
    return when (T::class) {
            UserId::class -> UserIdParser() as Parser<T>
            Shelf::class -> UserShelvesParser() as Parser<T>
            else -> throw Exception("can't match proper parser")
        }
}

internal interface Parser<out T: Model> {
    fun parse(xml: String): T
}


internal class UserIdParser : Parser<UserId> {
    override fun parse(xml: String): UserId {
        return parseUserId(xml)
    }
}

internal class UserShelvesParser : Parser<Shelf> {
    override fun parse(xml: String): Shelf {
        return parseShelf(xml)
    }
}
// for example
internal fun parseUserId(xml: String) = UserId("123", "owl", "ya.ru")
internal fun parseShelf(xml: String) = Shelf("123", "to-read", 20)

Итак, в коде клиента я мог бы написать так:

val t = getParser<UserId>().parse("")

Это работает, но при getParser методе у меня предупреждение Unchecked cast from UserIdParser to Parser<T>.Как я могу добиться такого поведения в kotlin, без предупреждений идиоматическим способом?

1 Ответ

3 голосов
/ 08 марта 2019

Это немного отличается от того, к чему вы стремитесь, но работает без предупреждения:

internal interface Model

data class UserId(val id: String, val name: String, val link: String) : Model
data class Shelf(val id: String, val name: String, val bookCount: Int) : Model

internal inline fun <reified T : Model> parse(xml: String) = when (T::class) {
    UserId::class -> parseUserId(xml)
    Shelf::class -> parseShelf(xml)
    else -> throw Exception("can't match proper parser")
} as T

// for example
internal fun parseUserId(xml: String) = UserId("123", "owl", "ya.ru")

internal fun parseShelf(xml: String) = Shelf("123", "to-read", 20)

, тогда его можно назвать так:

val t = parse<UserId>("")

Надеюсь, что это можетпомочь вам.

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