Me preguntaba si era posible agrupar una llamada a una función que está presente para dos tipos diferentes, sin tener que crear dos ramas en la declaración "cuando".
Por ejemplo, en mi caso tengo estas extensiones de clase:
// File: PublisherExtensions.kt fun <T> Mono<T>.toServiceResponse(): Mono<Response<T>> = this.map { r -> Response(true, r, null) } .onErrorResume { e -> Mono.just(Response(false, null, Response.Error(500, e.message))) } fun <T> Flux<T>.toServiceResponse(): Mono<Response<List<T>>> = this.collectList() .map { r -> Response(true, r, null) } .onErrorResume { e -> Mono.just(Response(false, null, Response.Error(500, e.message))) }Y lo que uso con ellos es esta declaración:
val body = when (val value = result.returnValue) { is Mono<*> -> value.toServiceResponse() is Flux<*> -> value.toServiceResponse() else -> throw RuntimeException("The \"body\" should be Mono<*> or Flux<*>!") }Mientras que lo que me gustaría sería esto:
val body = when (val value = result.returnValue) { is Mono<*>, is Flux<*> -> value.toServiceResponse() else -> throw RuntimeException("The \"body\" should be Mono<*> or Flux<*>!") }El IDE me da este error:
Referencia no resuelta.
Ninguno de los siguientes candidatos es aplicable debido a la falta de coincidencia del tipo de receptor:
- public fun Flux<TypeVariable(T)>.toServiceResponse(): Mono<Response<List<TypeVariable(T)>>> definido en brc.studybuddy.backend.wrapper.util en el archivo PublisherExtensions.kt
- diversión pública Mono<TypeVariable(T)>.toServiceResponse(): Mono<Response<TypeVariable(T)>> definido en brc.studybuddy.backend.wrapper.util en el archivo PublisherExtensions.kt
Tenga en cuenta que el segundo toServiceResponse se puede definir en términos del primero:
fun <T> Flux<T>.toServiceResponse(): Mono<Response<List<T>>> = this.collectList().toServiceResponse() Entonces, casi está haciendo lo mismo en Mono s y Flux es, excepto que para Flux es, también llama primero a collectList .
val body = when (val value = result.returnValue) { is Mono<*> -> value is Flux<*> -> value.collectList() else -> throw RuntimeException("The \"body\" should be Mono<*> or Flux<*>!") }.toServiceResponse() Alternativamente, sin un when :
val body = result.returnValue.let { value -> (value as? Flux<*>)?.collectList() ?: (value as? Mono<*>) ?: throw RuntimeException("The \"body\" should be Mono<*> or Flux<*>!") }.toServiceResponse()