Почему перегрузка функции подтипа невозможна с закрытыми классами Kotlin? - PullRequest
0 голосов
/ 14 мая 2018

Допустим, у меня есть запечатанный класс, который я использую для ответа сервера:

sealed class Response{
    class Success: Response() 
    class ErrorA: Response() 
    class ErrorB: Response() 
}

И поддельный ответ:

fun getResponse(): Response{
    val r = Random()
    return when (r.nextInt(3)) {
        0 -> { Response.Success() }
        1 -> { Response.ErrorA() }
        2 -> { Response.ErrorB() }
        else -> { throw IllegalStateException() }
    }
}

И я хочу обработать ответ.В настоящее время я мог бы использовать что-то вроде этого:

fun handle(response: Response) = when (response) {
    is Response.Success -> { handle(response) }
    is Response.ErrorA -> { handle(response) }
    is Response.ErrorB -> { handle(response) }
}

, что компилятор будет гарантировать, обрабатывает все случаи.Удивительная особенность!

Почему, однако, я не мог сделать что-то подобное:

class ResponseHandler(){

    fun handle(success: Response.Success) {}

    fun handle(error: Response.ErrorB) {}

    fun handle(error: Response.ErrorA) {}
}

и позвонить

ResponseHandler().handle(response)

Это достигает того же, но не делаетКомпиляция, мой вопрос заключается в следующем: так же, как компилятор гарантирует, что во время выполнения все случаи обрабатываются в операторе when, почему такая же логика не может быть применена к перегрузке метода?

Любойинформация или ссылки для дальнейшего чтения были бы чрезвычайно полезными.Спасибо

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

В принципе это можно сделать (по сути, автоматически генерируя метод handle(response: Response) = when ...). Но я не думаю, что это когда-либо случится. Перегрузка в Kotlin работает в основном так же, как и в Java / Scala / других языках JVM, и внесение существенных отличий за столь незначительную выгоду не выглядит хорошей идеей (конечно, это не относится к when, который специфичен для Kotlin ).

Если вы хотите, вы можете просто определить тот же fun handle(response: Response) внутри ResponseHandler (и сделать другие handle методы open, так что это действительно полезно).

0 голосов
/ 14 мая 2018

Эта проблема может быть разбита на этот упрощенный пример:

fun calc(i: Int) = i * 2
fun calc(d: Double) = d * 2

fun main(args: Array<String>) {
    val i: Number = 5
    calc(i)
}

У вас есть два специализированных метода, которые принимают Int и Double соответственно.Ваше значение имеет тип Number ( супертип обоих, Int и Double).Хотя i, очевидно, является целым числом, ваша переменная имеет тип Number, который не может быть аргументом либо calc(i: Int), либо calc(d: Double).

В вашем случае вы получаете Response ихочу вызвать один из перегруженных методов, ни один из которых не принимает Response напрямую.

...