Home > front end >  What is the return type for multiple possible types in Kotlin?
What is the return type for multiple possible types in Kotlin?

Time:04-29

fun getSummary(id: String): List<Summary> {
    val request = GetSummaryRequest(id)
    val response = client.getSummary(request) as GetSummaryResponse
    return when (val result = response.result) {
        is GetSummarySuccessResponse-> result.summaryList
        is GetSummaryFailResponse-> throw TreasuryRpcException("There was an error calling getSummary")
        else -> "No message"                      
        }
    }

it gives me a red line for :List<Summary> because return can be List<Summary>, Exception,String, I know I probably can use Any as return type. Just want to know the best practice in this case. Thanks!

CodePudding user response:

The exception is thrown so it is not part of the return type. You should return either emptyList() or null for the else condition so the return type can still be List<Summary> or at least List<Summary>?. You only need nullability if you need to distinguish that condition from a successful result.

CodePudding user response:

You probably need to use sealed class in this case.

First of all create a sealed class as follows:

sealed class Resource<out R>

data class Success<out R>(val data: R) : Resource<R>()
data class Failed(val t: Throwable? = null) : Resource<Nothing>()
data class Info(val message: String = "Something went wrong") : Resource<Nothing>()

In your code change the return type from List<Summary> to Resource<List<Summary>>. After changing, the code will look like following:

fun getSummary(id: String): Resource<List<Summary>> {
    val request = GetSummaryRequest(id)
    val response = client.getSummary(request) as GetSummaryResponse
    return when (val result = response.result) {
        is GetSummarySuccessResponse-> Success(result.summaryList)
        is GetSummaryFailResponse->  Failed(TreasuryRpcException("There was an error calling getSummary"))
        else -> Info("No message")                      
    }
}

The code where you call getSummary() should look like following:

val summaryResource = getSummary(id)
when(summaryResource) {
    is Success -> {
        val summary = summaryResource.data
        // Do something with summary
    }
    is Failed -> {
        val t = summaryResource.t
        println(t?.message)
        // Do something with t
    }
    is Info -> {
        val msg = summaryResource.message
        println(msg)
        // Do something with msg
    }
}
  • Related