-
-
Save aardouin/301eb88dcc2144a8090761e960ec9a13 to your computer and use it in GitHub Desktop.
//l'idée était de reproduire ce comportement de swift mais en kotlin | |
if let a = a { | |
//a is not null | |
}else{ | |
//a is null | |
} | |
//la solution avec les Standard kotlin : | |
a?.also{ it -> | |
//a is not null | |
}?: run { | |
//a isNull | |
} | |
//je trouve ça pas très parlant, surtout à cause du run en fait | |
//Du coup j'ai fait deux mini fonctions et ça s'utilise comme ça et c'est réversible : | |
a.isNotNull { it -> | |
//a is not null and accessible as it | |
}.isNull { | |
//a is null | |
} | |
//Ca ne résoue pas les cas ou on veux récupérer une valeur a la sortie typiquement si on veux faire | |
val value = if(str != null) str else "undefined" | |
//Sur le nommage j'hésite avec plusieurs noms | |
isSet / isNull | |
ifSet / ifNull | |
ifNotNull / ifNull | |
notNull / otherwise | |
//J'aurais aimé ton ressenti d'expert kotlin là dessus, que ce soit sur le nommage ou l'implémentation | |
//Ou alors que je me fais chier parcequ'en fait ça existe déjà et je suis un tocard | |
//la définition : | |
inline fun <T> T?.isNotNull(block: (T) -> Unit):T? { | |
return this?.also(block) | |
} | |
inline fun <T> T?.isNull(block: () -> Unit): T? { | |
this?: block() | |
return this | |
} |
J'en ai parlé à la team iOS et il y a une nuance importante avec le guard
que je propose car le guard
sur iOS oblige au niveau du compilateur à return
ou throw
dans le block de complétion :)
Après ce guard
que je propose est à mon sens une bonne alternative. Sinon le isNotNull
/isNull
que tu proposes marche aussi même si ça n'apporte pas énormément par rapport à un if/else hormis le scope sur ton objet. Mais si tu as vmt besoin du scope peut être que takeIf
est une meilleure alternative ;)
Dis moi ce que tu en penses :)
Ouai en fait ton guard
fait la meme chose que mon ifNull
au final, tu as juste écrit if == null
alors que j'ai utilisé le elvis.
Le but le mon ifNull / ifNotNull c'est surtout de pouvoir faire ce genre de choses
ticket.validationDate.ifNotNull {
validationDateTV.text = resources.getString(R.string.event_action_validation_date_detail_ticket,
it.toString(dateFormat),
it.toString(timeFormat))
}.ifNull {
validationDateTV.setText(R.string.event_action_validation_date_detail_ticket_no_date)
}
Je pourrais aussi écrire, mais du du coup je suis pas scopé :
validationDateTV.text = if(ticket.validationDate!= null){
resources.getString(R.string.event_action_validation_date_detail_ticket,
ticket.validationDate?.toString(dateFormat),
ticket.validationDate?.toString(timeFormat))
}else{
resources.getString(R.string.event_action_validation_date_detail_ticket_no_date)
}
Concernant le takeIf
j'aime bien aussi , mais du coup c'est assez verbeux et ça me supprime pas l'optionnel.
Je me dis que quitte à essayer de dupliquer ce comportement on aurait davantage intérêt à dupliquer le comportement de
guard
qui pour le coup vérifie que ta valeur est présente et la renvoit, sinon te fournit un block qui correspond pour le coup à tonelse
.On aurait qqchose comme ça
Sinon tu as le
takeIf
ou juste le elvis operator qui peut être intéressant selon les situationsD'ailleurs j'ai trouvé la plupart de ces choses dans cet article qui je trouve explique plutôt bien la problématique.