2016-10-19 3 views
2

Ich habe ein Objekt von einer API zurückgegeben, die verschiedene Nullable Felder hat. Ich möchte ein anderes Objekt mit nicht nullbaren Feldern erstellen oder null zurückgeben, wenn dies nicht möglich ist. Was ist die Sprache, die am besten zu diesem Szenario passt? Derzeit verwende ich ?.let {} und es sieht ziemlich hässlich:Konvertieren von Objekt mit Nullable-Feldern in ein Objekt mit nicht nullbaren Feldern oder null

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 ?: "") 
         } 
        } 
       } 
      } 
     } 
    } 
} 

Antwort

4

Wenn Ihre Klassen AnswerGson und AnswerResponseGson haben ihre Eigenschaften als val erklärt, können Sie Ihren Code so etwas wie dies konvertieren:

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 ?: "") 
} 

Dieses Beispiel verwendet smart casts: Der Compiler analysiert den Kontrollfluss und beweist, dass, wenn die letzte Anweisung reac ist Dann ist keiner der oben geprüften Werte null.

Diese Prüfungen werden nicht auf sichere Dereferenzierungsketten angewendet, und ich musste zuerst answerResponse.answer und erst dann answerResponse.answer.id überprüfen.


Wenn Sie var Eigenschaften haben, können intelligente Abgüsse nicht angewendet werden, da der Wert ändern könnte, nachdem sie überprüft wird.

In diesem Fall können Sie immer noch die Verschachtelung in Ihrem Code reduzieren, indem die Werte in die lokalen Variablen zu extrahieren und sie zur gleichen Zeit überprüft:

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 ?: "") 
} 

Und wie @mfulton26 bemerkt haben, können Sie auch diese Inline Variablen (arbeitet für val s als auch):

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 ?: "") 
} 
+4

Wow ... ich habe erkannt, dass all diese lokalen Variablen auch inlined werden können, wenn man sie nicht wollen. z.B. '... zurück AnswerResponseUi (userAnswer.id?: Rückgabe null, answerResponse.answer? .id?: Rückgabe null, ...' – mfulton26

+0

Lesbarkeit ist der Schlüssel, also versuche nicht, alles inline;) Aber das ist wirklich beeindruckend! – voddan

Verwandte Themen