Convertir object con campos anulables en un object con campos que no admiten nulos o nulo

Tengo un object devuelto por una API, que tiene diferentes campos anulables. Quiero crear otro object con campos no anulables o devolver nulo si no es posible. ¿Cuál es la expresión idiomática que mejor se adapta a ese escenario? Actualmente estoy usando ?.let {} y se ve bastante feo:

 fun convertAnswer(userAnswer: AnswerGson, answerResponse: AnswerResponseGson, correctAnswerText: String): AnswerResponseUi? { return userAnswer.id?.let { userAnswerId -> userAnswer.text?.let { userAnswerText -> answerResponse.answer?.id?.let { correctAnswerId -> answerResponse.points?.let { points -> answerResponse.discount?.let { discount -> answerResponse.booster?.let { booster -> return AnswerResponseUi(userAnswerId, correctAnswerId, userAnswerText, correctAnswerText, points, discount, booster.name ?: "") } } } } } } } 

Si sus classs AnswerGson y AnswerResponseGson tienen sus properties declaradas como val , puede convertir su código a algo como esto:

 fun convertAnswer(userAnswer: AnswerGson, answerResponse: AnswerResponseGson, correctAnswerText: String): AnswerResponseUi? { if (userAnswer.id == null || userAnswer.text == null || answerResponse.discount == null || answerResponse.points == null || answerResponse.booster == null || answerResponse.answer == null || answerResponse.answer.id == null ) return null return AnswerResponseUi(userAnswer.id, answerResponse.answer.id, userAnswer.text, correctAnswerText, answerResponse.points, answerResponse.discount, answerResponse.booster.name ?: "") } 

Este ejemplo usa moldes inteligentes : el comstackdor analiza el flujo de control y testing que si se alcanza la última instrucción, ninguno de los valores marcados arriba es null .

Estas verificaciones no se aplican a las cadenas de desreference seguras, y tuve que verificar primero answerResponse.answer y solo luego answerResponse.answer.id .


Si tiene properties de var , no se pueden aplicar moldes inteligentes porque el valor puede cambiar después de que se marque.

En este caso, puede networkingucir la anidación en su código extrayendo los valores en variables locales y verificándolos al mismo time:

 fun convertAnswer(userAnswer: AnswerGson, answerResponse: AnswerResponseGson, correctAnswerText: String): AnswerResponseUi? { val answerId = userAnswer.id ?: return null val correctAnswerId = answerResponse.answer?.id ?: return null val userAnswerText = userAnswer.text ?: return null val points = answerResponse.points ?: return null val discount = answerResponse.discount ?: return null val booster = answerResponse.booster ?: return null return AnswerResponseUi(answerId, correctAnswerId, userAnswerText, correctAnswerText, points, discount, booster.name ?: "") } 

Y, como @mfulton26 notó, incluso puedes alinear estas variables (también funciona para val s):

 fun convertAnswer(userAnswer: AnswerGson, answerResponse: AnswerResponseGson, correctAnswerText: String): AnswerResponseUi? { return AnswerResponseUi(userAnswer.id ?: return null, answerResponse.answer?.id ?: return null, userAnswer.text ?: return null, correctAnswerText, answerResponse.points ?: return null, answerResponse.discount ?: return null, (answerResponse.booster ?: return null).name ?: "") } 
  • Referencia no resuelta: Kotlin necesita 2 versiones después de limpiar para recoger el código cuando usa kapt
  • Exponenciación de Kleisli en Kotlin
  • Cómo acceder a los objects-miembros de una statement de object en kotlin
  • No se pudo deducir Kotlin y RxJava
  • ¿Cuál es el equivalente de los methods estáticos de Java en Kotlin?
  • ¿Cuál es la diferencia entre Int y Integer en Kotlin?
  • Seleccionar datos de dos tablas en Kotlin Anko
  • Cómo deshabilitar el button de punto en Android Kotlin
  • La interfaz de Java SAM creada a partir de Kotlin da ClassCastException
  • Redondeando un doble a dos decimales en Kotlin. BigDecimal.doubleValue no existe?
  • Kotlin DSL para crear objects json (sin crear basura)